Home > Software design >  How to test my custom JPA query using @DataJpaTest?
How to test my custom JPA query using @DataJpaTest?

Time:05-05

I wrote this repository including a custom query:

@Repository
interface PersonRepository : JpaRepository<Person, UUID> {

    @Query("UPDATE Person SET firstname = :firstname, lastname = :lastname WHERE id IN :ids")
    @Modifying
    fun updateNames(firstname: String, lastname: String, ids: List<UUID>) : Int
}

and implemented the following test for it:

@DataJpaTest
@AutoConfigureTestDatabase(replace = NONE)
internal class PersonRepositoryIntegrationTest {

    @Autowired
    lateinit var personRepository: PersonRepository

    @Test
    @Commit
    fun updateNames() {

        // GIVEN
        // insert some records
        personRepository.save(Person(UUID.randomUUID(), "Homer", "Simpson"))
        personRepository.save(Person(UUID.randomUUID(), "Bart", "Simpson"))
        personRepository.save(Person(UUID.randomUUID(), "Marge", "Simpson"))

        // read back the ids and assert lastname before updating
        val readBeforeUpdate = personRepository.findAll()
        assertTrue(readBeforeUpdate.isNotEmpty())
        assertTrue(readBeforeUpdate.all { it.lastname == "Simpson" })
        val ids = readBeforeUpdate.map { it.id }

        // WHEN
        val count = personRepository.updateNames("John", "Doe", ids)
        personRepository.flush()

        // THEN
        assertEquals(3, count)
        val readAfterUpdate = personRepository.findAll()
        println(readAfterUpdate)
        assertEquals(3, readAfterUpdate.size)
        assertTrue(readAfterUpdate.all { it.firstname == "John" && it.lastname == "Doe" })
    }

}

which fails at the last line, verifying made changes, e.g. first and lastname. I added @Commit to prevent the automatic rollback spring would do, so that I can check the data afterwards. I can see the changed names in the database, so it looks like my query works. My suspicion is, that val readAfterUpdate = personRepository.findAll() is either

  • executed in different transaction from personRepository.updateNames and can not "see" the other transaction's changes yet
  • or personRepository.findAll() is returned from Hibernate's cache or something

What am I missing here? How to make the test work? Or what would be another approach to check if the data was indeed changed in the database?

An example project showcasing the behaviour is available at https://github.com/timbuethe/SpringBootDataTest

CodePudding user response:

I think the use of @Modifiying leave the persistence context outdated so maybe adding (clearAutomatically = true) could solve the issue

  • Related