如何使用@DataJpaTest 测试我的自定义 JPA 查询?
How to test my custom JPA query using @DataJpaTest?
我编写了这个包含自定义查询的存储库:
@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
}
并为其实施了以下测试:
@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" })
}
}
在最后一行失败,验证所做的更改,例如名字和姓氏。
我添加了 @Commit
以防止自动回滚 spring 会做,以便我以后可以检查数据。我可以在数据库中看到更改后的名称,所以看起来我的查询有效。
我怀疑 val readAfterUpdate = personRepository.findAll()
是
- 在与
personRepository.updateNames
不同的事务中执行,还不能“看到”其他事务的更改
- 或
personRepository.findAll()
从Hibernate的缓存或其他东西返回
我在这里错过了什么?如何使测试工作?或者还有什么方法可以检查数据库中的数据是否确实发生了变化?
获取展示该行为的示例项目
我认为使用 @Modifiying
会使持久性上下文过时,所以也许添加 (clearAutomatically = true)
可以解决问题
我编写了这个包含自定义查询的存储库:
@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
}
并为其实施了以下测试:
@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" })
}
}
在最后一行失败,验证所做的更改,例如名字和姓氏。
我添加了 @Commit
以防止自动回滚 spring 会做,以便我以后可以检查数据。我可以在数据库中看到更改后的名称,所以看起来我的查询有效。
我怀疑 val readAfterUpdate = personRepository.findAll()
是
- 在与
personRepository.updateNames
不同的事务中执行,还不能“看到”其他事务的更改 - 或
personRepository.findAll()
从Hibernate的缓存或其他东西返回
我在这里错过了什么?如何使测试工作?或者还有什么方法可以检查数据库中的数据是否确实发生了变化?
获取展示该行为的示例项目我认为使用 @Modifiying
会使持久性上下文过时,所以也许添加 (clearAutomatically = true)
可以解决问题