Skip to content

No transaction in progress for @Nested test class #34576

@bernie-schelberg-invicara

Description

Overview

In a Spring Boot project, with a test such as this:

@DataJpaTest
class PersonRepositoryTest {

    @Autowired
    PersonRepository personRepository;

    @Autowired
    TestEntityManager em;

    @BeforeEach
    void setup() {
        em.persistAndFlush(new Person());
    }

    @Test
    void shouldFindAllPersons() {
        Iterable<Person> result = personRepository.findAll();

        assertThat(result).hasSizeGreaterThanOrEqualTo(1);
    }

    @Nested
    @TestPropertySource(properties = "spring.config.additional-location=optional:file:data.yaml")
    class FindAll {

        @Test
        void shouldFindAllPersons() {
            Iterable<Person> result = personRepository.findAll();

            assertThat(result).hasSizeGreaterThanOrEqualTo(1);
        }
    }
}

The test in the @Nested class fails with:

jakarta.persistence.TransactionRequiredException: no transaction is in progress

The test in the outer class works fine.

Removing the @TestPropertySource results in all tests passing, however in the test I'm actually working on, I need that to work around another bug. I assume that there are other scenarios which might cause this issue as well. I've spent some time debugging this, and it appears that 2 LocalContainerEntityManagerFactoryBeans are created - the transaction is started with one of them, but the code in the @BeforeEach is executed using the other. This results in the TransactionSynchronisationManager not finding the EntityManagerHolder in doGetResource().

The issue is present in 3.2.3, 3.2.12 and 3.4.3, and presumably everything in-between.

The root cause of the issue appears to be that an application context is created for the outer class, and the TestEntityManager is injected from that one, but then another application context is created for the inner class (which makes sense, since the configuration is different), and the transaction is started with the entity manager from the inner class' application context. However, the TestEntityManager has been injected from the outer class' application context, and any operations done using it do not have a transaction in progress.

I initially raised this issue against Spring Boot (spring-projects/spring-boot#44679), but after more investigation, it appears to be an issue with spring-test (present in version 6.2.3).

Related Issues

Metadata

Metadata

Assignees

Labels

in: testIssues in the test modulestatus: supersededAn issue that has been superseded by another

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions