Search code examples
spring-dataspring-boot-test

How not to rollback @DataJpaTest?


In the following code

@DataJpaTest
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
public class GenreDaoJpaTest{
    @Autowired
    private TestEntityManager entityManager;
    @Autowired
    private GenreRepository dao;
    ....   
}

when I'm adding @Transactional(propagation = Propagation.NOT_SUPPORTED) with the purpose to cancel a roolback after each test I'm getting an exception:

ava.lang.IllegalStateException: No transactional EntityManager found

    at org.springframework.util.Assert.state(Assert.java:73)
    at org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager.getEntityManager(TestEntityManager.java:237)
    at org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager.persist(TestEntityManager.java:92)
    at ru.otus.ea.dao.GenreDaoJpaTest.init(GenreDaoJpaTest.java:38)

It there a way to autowire TestEntityManager and not to roolback transactions in tests?


Solution

  • Your TestEntityManager is autowired but you are executing the persist call outside of a transaction.

    You can autowire TransactionTemplate:

        @Autowired
        private TransactionTemplate transactionTemplate;
    

    And execute your DB interactions using its execute method:

        User savedUser = transactionTemplate.execute((conn) -> {
            return testEntityManager.persist(new User("foo"));
        });
    

    Also you should be aware that now you are responsible for cleanup of test DB after tests execute (which might be hard to maintain as logic grows):

        @BeforeEach // just to be sure
        @AfterEach
        public void cleanup() {
            userRepository.deleteAll();
        }