20

这些 jar 都是新发布的,并且具有 Java EE 应用程序的最新解决方案。但是我在 hibernate.cfg.xml 中指定休眠侦听器时遇到问题。

在 spring 3.1.0 之前,LocalSessionFactroyBean持有一个保持事件监听器的属性。但是在 3.1.0.release 中没有 eventlisteners 映射。现在我无法在 saveorupdate、postload 等上跟踪模态对象,因为它们不是由 Spring 配置的。你有解决这个问题的想法吗?

4

4 回答 4

37

我有同样令人沮丧的问题。Hibernate 4 似乎从根本上改变了您注册事件的方式,而 Spring 组尚未赶上。这是我使用 init 方法注册侦听器的基于注释的解决方案:

@Component
public class HibernateEventWiring {

    @Autowired
    private SessionFactory sessionFactory;

    @Autowired
    private SomeHibernateListener listener;

    @PostConstruct
    public void registerListeners() {
        EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
        EventListenerRegistry.class);
        registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(listener);
        registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(listener);
    }
}

拦截器将是另一种很好的方法,但错误地放弃了对拦截器的支持:https ://jira.springsource.org/browse/SPR-8940

于 2012-01-25T22:38:20.223 回答
14

新方法是使用 Integrator 来注册事件侦听器。Hibernate 现在将使用服务发现来注册事件侦听器,这是我使用 maven archetype-webapp 使其工作的方法

在 META-INF/services 下创建一个名为 org.hibernate.integrator.spi.Integrator 的文件,其中包含实现 hibernate spi 接口的所有类,每行一行。下面的简短示例:

...

META-INF/services/org.hibernate.integrator.spi.Integrator

com.example.CustomIntegrator

com.example.CustomIntegrator

package com.example;

import ...;

public void CustomIntegrator implements Integrator {

    static final Logger logger = LoggerFactory.getLogger(CustomIntegrator.class);

    @Override
    public void integrate(Configuration configuration, SessionFactoryImplementor implementor, SessionFactoryServiceRegistry registry) {
        final EventListenerRegistry eventRegistry = registry.getService(EventListenerRegistry.class);

        logger.info("Registering event listeners");
        // you can add duplication strategory for duplicate registrations
        ...

        // prepend to register before or append to register after
        // this example will register a persist event listener
        eventRegistry.prependListeners(EventType.PERSIST, myListener);
        ...
    }

    ...

}

com.example.MyListener

package com.example;

import ...

public class MyListener implements PersistEventListener {

    static final Logger logger = LoggerFactory.getLogger(MyListener.class);

    public void onPersist(PersistEvent event) throws HibernateException {
        logger.debug("Entering MyListener");

        if(event.getObject() instanceof MyPersistableEntity) {
            MyPersistableEntity entity = (MyPersistableEntity) event.getObject();
            // do something with entity
            ...
        }
    }

    ...
}

任何需要注册此事件的实体都必须实现 MyPersistableEntity(此处未显示)

于 2012-07-26T15:08:16.273 回答
4

您可能想查看 Hibernate Ticket [1]:https ://hibernate.onjira.com/browse/HHH-6945

迁移指南说:

不再支持 hibernate.cfg.xml 作为指定侦听器的方法。新方法涉及使用基于“服务发现”工作的 org.hibernate.integrator.spi.Integrator。

你可以得到完整的说明@http: //in.relation.to/Bloggers/EventListenerRegistration

票证中的链接有问题,请使用以下内容:

https://github.com/hibernate/hibernate-orm/blob/master/hibernate-envers/src/main/java/org/hibernate/envers/event/EnversIntegrator.java

https://github.com/hibernate/hibernate-orm/blob/master/hibernate-envers/src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator

希望这可以帮助寻找这个问题的答案的人。

于 2012-06-11T19:24:51.380 回答
0

在通过上述响应中提到的 EventListenerRegistry 类附加自定义事件侦听器时,需要确保删除默认事件侦听器。否则,如果在您的应用程序中存在 onetomany 映射,则将抛出“休眠异常:对集合的共享引用:xyz”异常

于 2018-01-18T18:15:50.297 回答