Resetting Database Between Spring Integration Tests

When tasked with having to write an integration test or a Spring Webflux test that uses a database, it can be cumbersome to have to reset the database between each test by using @DirtiesContext. Using @DirtiesContext slows down your build significantly since everything, including beans, needs to be reloaded between tests. This post will explain how you can reset the database between tests. I created a sample Spring Boot project if you’d like to check out a working simple example.

The main issue of trying to reset the database is to find out what tables exist without hardcoding anything. This can be accomplished by looking at the Autowired EntityManager and then running truncate commands. Let’s start with creating a service that will do what we want called TestDbService. Since this is a dangerous service, we’re going to place this in the test module and not the actual code module.

public class TestDbService {

    // Autowired via constructor based injected (using Lombok for generated constructor)
    private final EntityManager entityManager;
    private List<String> tableNames;

    void afterPropertiesSet() {
        tableNames = entityManager.getMetamodel().getEntities().stream()
            .filter(entityType -> entityType.getJavaType().getAnnotation(Table.class) != null)
            .map(entityType -> entityType.getJavaType().getAnnotation(Table.class))
            .map(this::convertToTableName) // TODO

First we’re going to query the metadata and grab everything from the @Table annotations. Then we’re going to convert the name that we need to use for h2 database. Depending on how you make your tables, you may not need this but If you have a table named CamelCaseTable, then h2 is going to create a table named Camel_Case_Table, so we can’t use the name you use as-is for the truncate commands. We need our truncate statement to reflect the correct name. We can fix this with some regex in the convertToTableName(Table table) function below:

     * Converts an (optional) schema and table on a {@link Table} annotation to something that h2
     * uses when it generates tables.
    private String convertToTableName(Table table) {
        String schema = table.schema();
        String tableName =;

        String convertedSchema = StringUtils.hasText(schema) ? schema.toLowerCase() + "." : "";
        String convertedTableName = tableName.replaceAll("([a-z])([A-Z])", "$1_$2");

        return convertedSchema + convertedTableName;

Using the regex make it now we know tables that the h2 database in actually using. The schema part of optional in case you define the schema in your @Table annotations. This will convert it to Schema.Table_name.

Now that we have the tables to convert, we just need to delete the entries. We’ll do this with a new service method named resetDatabase().

    public void resetDatabase() {
        entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate();

        for (String tableName : tableNames) {
            entityManager.createNativeQuery("TRUNCATE TABLE " + tableName).executeUpdate();

        entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY TRUE").executeUpdate();

Here we’re getting away with truncating the tables in any order with the referential integrity disablement and reenablement.

Now to bring it all together, we need a test that calls this new service. This is accomplished by calling the service in an @AfterEach method. The example test below is just running the same code twice with no dirty context calls. Without calling the TestDbService, one of the tests would fail since the number of users found would be 4 instead of 2.

 * This test class would be much better served as a {@link DataJpaTest}. (where the TestDbService wouldn't be needed). This is a {@link
 * SpringBootTest} only to show a simple test of using the {@link TestDbService}.
class ImportantUserRepositoryTest {

    private ImportantUserRepository importantUserRepository;

    private TestDbService testDbService;

    private ImportantUser user1;
    private ImportantUser user10;
    private ImportantUser user20;

    void beforeEach() {
        user1 = ImportantUser.builder()

        user10 = ImportantUser.builder()

        user20 = ImportantUser.builder()

        user1 =;
        user10 =;
        user20 =;

    void afterEach() {

    void findByFistNameLikeOrLastNameLike() {
        List<ImportantUser> foundUsers = importantUserRepository.findByFistNameLikeOrLastNameLike("10");

        assertThat(foundUsers, hasSize(2));
        assertThat(foundUsers.get(0).getId(), is(user1.getId()));
        assertThat(foundUsers.get(1).getId(), is(user10.getId()));

    void findByFistNameLikeOrLastNameLike2() {
        List<ImportantUser> foundUsers = importantUserRepository.findByFistNameLikeOrLastNameLike("10");

        assertThat(foundUsers, hasSize(2));
        assertThat(foundUsers.get(0).getId(), is(user1.getId()));
        assertThat(foundUsers.get(1).getId(), is(user10.getId()));

And that’s it! Again check out the Github sample project if you’d like to see a working example.

About the Author

Object Partners profile.
Leave a Reply

Your email address will not be published.

Related Blog Posts
Building Better Data Visualization Experiences: Part 1 of 2
Through direct experience with data scientists, business analysts, lab technicians, as well as other UX professionals, I have found that we need a better understanding of the people who will be using our data visualization products in order to build them. Creating a product utilizing data with the goal of providing insight is fundamentally different from a typical user-centric web experience, although traditional UX process methods can help.
Kafka Schema Evolution With Java Spring Boot and Protobuf
In this blog I will be demonstrating Kafka schema evolution with Java, Spring Boot and Protobuf.  This app is for tutorial purposes, so there will be instances where a refactor could happen. I tried to […]
Redis Bitmaps: Storing state in small places
Redis is a popular open source in-memory data store that supports all kinds of abstract data structures. In this post and in an accompanying example Java project, I am going to explore two great use […]
Let’s build a WordPress & Kernel updated AMI with Packer
First, let’s start with What is an AMI? An Amazon Machine Image (AMI) is a master image for the creation of virtual servers in an AWS environment. The machine images are like templates that are configured with […]