事件监听器没有在Hibernate上工作?

时间:2017-02-17 16:02:48

标签: spring hibernate events listener

我已经实现了一个事件监听器,用于对我的实体进行审计操作。例如,我为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。

2 个答案:

答案 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的更高版本使用了另一个你尚未实现的签名。这可能就是你的听众没有开火的原因。