我目前正在尝试构建钩子来获取存储库的所有成功提交的实体更改的列表:
@Entity data class User(@Id val id: Long, val name: String)
interface extends JpaRepository<User, Long>
@Service
class UserService(val userRepository:UserRepository){
@Transactional
fun someProcess(){
val newUser = User()
newUser.name = "newUser"
userRepository.save(newUser)
val userToUpdate = userRepository.findById(1).get()
userToUpdate.name = "updatedUser"
val userToDelete = userRepository.findById(2).get()
userRepository.delete(userToDelete)
}
// TODO implement hooks
fun hookAllInserts(inserts :List<User>){
// list is expected to contain newUser
}
fun hookAllUpdates(updates: List<User>) {
// list is expected to contain the latest state of updatedUser
}
fun hookAllDeletions(deletions: List<User>){
// list is expected to contain the deletedUser
}
}
钩子只能在成功提交后触发,因此回滚的更改不会传播。
如何使用Spring数据实现这一点?
我还没有找到适用于所有Spring数据存储库的通用解决方案,但是当将Spring数据与hibernate结合使用时,有一个解决方案:
@Component
class ChangeListener(
private val entityManagerFactory: EntityManagerFactory,
) : PostUpdateEventListener, PostInsertEventListener, PostDeleteEventListener {
@PostConstruct
private fun init() {
val sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl::class.java)
val registry = sessionFactory.serviceRegistry.getService(EventListenerRegistry::class.java)
registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(this)
registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(this)
registry.getEventListenerGroup(EventType.POST_COMMIT_DELETE).appendListener(this)
}
override fun requiresPostCommitHanding(persister: EntityPersister): Boolean {
return true
}
override fun onPostUpdate(event: PostUpdateEvent) {
// event.entity contains the latest state of the entity
}
override fun onPostDelete(event: PostDeleteEvent) {
// event.entity contains the latest state of the entity
}
override fun onPostInsert(event: PostInsertEvent) {
// event.entity contains the last state of the entity
}
}
它基于Hibernate EventListeners
另见此处。
Vlad Mihalcea的博客上也有一篇不错的文章