我已经实现了一个事件监听器,用于对我的实体进行审计操作。例如,我为PreInsertEventListener创建了一个名为HibernatePreInsert的程序。另外,通过在stackoverflow上阅读这里我配置了一个名为HibernateIntegrator的Integrator。因为我正在使用Hibernate 4和spring 4,所以我在META-INF / services下创建了一个名为com.dacasals.raspertwo.interceptors.HibernateInterceptor的文件,并在那里添加了集成器类,如网上推荐的那样。但是当我运行我的应用程序并插入一个新元素时,没有任何反应,甚至没有显示我的HibernatePrePersist的消息。这是我第一次尝试使用Hibernate EventListeners而我不知道会出现什么问题。
以下是我的问题所涉及的类的示例,也是文件结构:
听众:
public class HibernatePreInsert implements PreInsertEventListener{
private static final long serialVersionUID = 1L;
static final Logger logger = LoggerFactory.getLogger(HibernatePreInsert.class);
@Override
public boolean onPreInsert(PreInsertEvent event) {
if(event.getEntity() instanceof Person){
//display a message to know if this works or not
logger.info("It works");
}
return false;
}
}
整编者:
public class HibernateIntegrator implements Integrator{
public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry){
final EventListenerRegistry registry = serviceRegistry.getService(EventListenerRegistry.class);
HibernatePreInsert listener = new HibernatePreInsert();
registry.prependListeners(EventType.PRE_INSERT, listener);
}
@Override
public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
// TODO Auto-generated method stub
}
@Override
public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
// TODO Auto-generated method stub
}
}
com.dacasals.raspertwo.interceptors.HibernateInterceptor文件:
com.dacasals.raspertwo.interceptors.HibernateInterceptor
提前致谢。
编辑: 我在写作时犯了一个错误。我正在使用Hibernate 5,而不是4。
答案 0 :(得分:4)
我让听众无需使用我之前找到的方法就能工作。我没有使用服务定义文件,而是创建了一个新类,我在其中注册了我实现的事件监听器,如下所示:
@Component
public class EscuchadorGeneral {
@PersistenceUnit
private EntityManagerFactory emf;
@Inject
private InsertEvent insert;
@Inject
private UpdateEvent update;
@Inject
private DeleteEvent delete;
@PostConstruct
protected void init(){
SessionFactoryImpl sF = emf.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sF.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.POST_INSERT).appendListener(insert);
registry.getEventListenerGroup(EventType.POST_UPDATE).appendListener(update);
registry.getEventListenerGroup(EventType.PRE_DELETE).appendListener(delete);
}
}
现在我可以在插入,更新或删除任何实体时收听。我希望这个解决方案也适用于其他开发人员。
答案 1 :(得分:2)
由于你想要做的就是操纵与事件相关的实体,我建议在这里使用@PrePersist
。
即使应用程序不使用任何JPA功能并继续使用本机SessionFactory
配置,您也可以欺骗Hibernate仍然触发JPA集成器回调。
对于5.2之前的Hibernate,您需要确保在依赖类路径中包含与hibernate-entitymanager
依赖项的相同版本匹配的相应版本化hibernate-core
。对于Hibernate 5.2及更高版本,您需要包含的是hibernate-core
,您显然已经使用了它。
接下来是设置META-INF/services/org.hibernate.integrator.spi.Integrator
。
对于4.2之前的Hibernate,您需要添加:
org.hibernate.ejb.event.JpaIntegrator
对于Hibernate 4.3和5.x,您需要添加:
org.hibernate.jpa.event.spi.JpaIntegrator
即使您的配置没有引导JPA @PrePersist
,您现在也应该可以使用EntityManager
回调。
然后,当您将应用程序移植到专门使用JPA时,最终可以删除此集成器配置,因为构建的JPA EntityManager
将自动注册并执行这些回调。
<强>更新强>
如果您决定要使用Hibernate EventListener
,我会确保两个integrate
方法都注册该侦听器。我认为你实现的那个留给了遗留合同,但我相信Hibernate的更高版本使用了另一个你尚未实现的签名。这可能就是你的听众没有开火的原因。