Home > OS >  Can share a transaction between EntittManager and a Repository
Can share a transaction between EntittManager and a Repository

Time:02-22

Is there a way to work with both EntityManager and some repositories in the same @Transactional method?

In the code below, I'd expect the last assest is successful.

@DataJpaTest
public class JobCategoryRepositoryTest {

    [...]

    @Test
    void save_and_check() {
        repository.save(JobCategory.builder("a1").build());
        repository.save(JobCategory.builder("a2").build());
        repository.save(JobCategory.builder("a3").build());
        repository.flush();

        assertThat(repository.getCount()).isEqualTo(3); // OK

        EntityManager em = entityManagerFactory.createEntityManager();
        List<JobCategory> results = em.createQuery("select j from JobCategory j", JobCategory.class).getResultList();
        assertThat(results.size()).isEqualTo(3); // NOT OK
    }

CodePudding user response:

You should apply TestEntityManager in tests. It's a wrapper that creates (or returns the existing one) EntityManager that is guaranteed to be bonded to the current running Spring transaction.

@DataJpaTest
public class JobCategoryRepositoryTest {

    @Autowired
    private TestEntityManager tem;

    @Test
    void save_and_check() {
        repository.save(JobCategory.builder("a1").build());
        repository.save(JobCategory.builder("a2").build());
        repository.save(JobCategory.builder("a3").build());
        repository.flush();

        assertThat(repository.getCount()).isEqualTo(3); // OK

        EntityManager em = tem.getEntityManager();
        List<JobCategory> results = em.createQuery("select j from JobCategory j", JobCategory.class).getResultList();
        assertThat(results.size()).isEqualTo(3); // OK
    }
  • Related