3

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

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that helped! After reading this answer: stackoverflow.com/a/57062549/60518 I ended up adding both clear- and flushAutomatically: @Modifying(clearAutomatically=true, flushAutomatically=true)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.