spring - Spring Boot 2.1.2、Hibernate 5:注册 Hibernate 事件监听器(插入/更新/删除)
问题描述
当我在之前的 Spring 应用程序中使用 Hibernate 4 时,以下内容足以注册所有对 DB Insert/Update/Delete 事件的拦截。有一个简单的配置类和实际的拦截器实现。
配置类
@Component
public class HibernateEntityEventListenerConfig {
@Autowired
private SessionFactory sessionFactory;
@Autowired
private HibernateEntityEventListener entityEventListener;
@PostConstruct
public void registerListeners() {
final EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory)
.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener((PreInsertEventListener) entityEventListener);
registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener((PreUpdateEventListener) entityEventListener);
registry.getEventListenerGroup(EventType.PRE_DELETE).appendListener((PreDeleteEventListener) entityEventListener);
}
}
拦截器类
@Component
public class HibernateEntityEventListener implements PreInsertEventListener,
PreUpdateEventListener,
PreDeleteEventListener {
@Override
public boolean onPreInsert(PreInsertEvent event) {
//...
}
@Override
public boolean onPreUpdate(PreUpdateEvent event) {
//...
}
@Override
public boolean onPreDelete(PreUpdateEvent event) {
//...
}
但是当我将此代码移植到使用 Hibernate 5 的 Spring Boot 2.1.2 应用程序时,我开始收到以下有关找不到SessionFactory的启动错误:
Field sessionFactory in util.HibernateEntityEventListenerConfig required
a bean of type 'org.hibernate.SessionFactory' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.hibernate.SessionFactory' in your configuration.
我四处搜索,只发现了一些我不信任或不理解的更复杂和混乱的代码, https://stackoverflow.com/a/48471227/1005607
现在这太复杂了,我只需要一种简单的方法来连接这个拦截器。放置拦截器并克服这个 SessionFactory 错误的正确方法是什么?
解决方案
我在Bozho 的博客上找到了解决方案,代码可以保持与以前大致相同,但我不能再自动接线SessionFactory
了:我必须改为自动接线EntityManagerFactory
,然后将其“解包”为SessinFactoryImpl sf = emf.unwrap(..)
. 这是唯一的变化。
最新代码: 配置:
@Component
public class HibernateEntityEventListenerConfig {
@PersistenceUnit
private EntityManagerFactory emf; // NOTE Can't autowire SessionFactory.
@Autowired
private HibernateEntityEventListener entityEventListener;
@PostConstruct
public void registerListeners() {
// NOTE the emf.unwrap() to get the SessionFactoryImpl
SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory)
.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener((PreInsertEventListener) entityEventListener);
registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener((PreUpdateEventListener) entityEventListener);
registry.getEventListenerGroup(EventType.PRE_DELETE).appendListener((PreDeleteEventListener) entityEventListener);
}
}
推荐阅读
- c# - 发布动态创建的 HTML 页面以形成操作
- php - 如何从 mysql db 中检索数据,而不是使用 php 中的 while 循环?
- android - Android - spotShadowAlpha 仅适用于线性布局
- ios - 当领域上的对象无效时该怎么办
- node.js - 在 AWS-EC2 实例上使用 Nginx 启动节点应用程序的问题
- php - 从会话中删除 Laravel
- python - pandas 中是否有一个选项来查看列中的值是否小于一行中的另一列,然后随着时间的推移而变化?
- javascript - localStorage 删除一个值并保留现有值
- r - 如何在列中搜索多个值,如果找到,则在同一行中填充另一列?
- windows - 在 IIS 上使用 .srf 文件部署网站时出现问题