Search code examples
javaspring-boottransactionsspring-dataspring-data-jpa

How to force transaction commit in Spring Boot test?


How can I force a transaction commit in Spring Boot (with Spring Data) while running a method and not after the method ?

I've read here that it should be possible with @Transactional(propagation = Propagation.REQUIRES_NEW) in another class but doesn't work for me.

Any hints? I'm using Spring Boot v1.5.2.RELEASE.

@RunWith(SpringRunner.class)
@SpringBootTest
public class CommitTest {

    @Autowired
    TestRepo repo;

    @Transactional
    @Commit
    @Test
    public void testCommit() {
        repo.createPerson();
        System.out.println("I want a commit here!");
        // ...
        System.out.println("Something after the commit...");
    }
}

@Repository
public class TestRepo {

    @Autowired
    private PersonRepository personRepo;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createPerson() {
        personRepo.save(new Person("test"));
    }
}

Solution

  • An approach would be to inject the TransactionTemplate in the test class, remove the @Transactional and @Commit and modify the test method to something like:

    ...
    public class CommitTest {
    
        @Autowired
        TestRepo repo;
    
        @Autowired
        TransactionTemplate txTemplate;
    
        @Test
        public void testCommit() {
            txTemplate.execute(new TransactionCallbackWithoutResult() {
    
              @Override
              protected void doInTransactionWithoutResult(TransactionStatus status) {
                repo.createPerson();
                // ...
              }
            });
    
            // ...
            System.out.println("Something after the commit...");
        }
    

    Or

    new TransactionCallback<Person>() {
    
        @Override
        public Person doInTransaction(TransactionStatus status) {
          // ...
          return person
        }
    
        // ...
    });
    

    instead of the TransactionCallbackWithoutResult callback impl if you plan to add assertions to the person object that was just persisted.