eventlisteners using hibernate 4.0 with spring 3.1.0.release?

You might wanna check the Hibernate Ticket [1]: https://hibernate.onjira.com/browse/HHH-6945

The migration guide says:

hibernate.cfg.xml no longer supported as means of specifying listeners. New approach invloves using an org.hibernate.integrator.spi.Integrator which works based on "service discovery".

And you can get the complete instructions @ http://in.relation.to/Bloggers/EventListenerRegistration

The links in the ticket have some issue, use the following:

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

Hope this helps someone looking answers for this problem.


I had the same frustrating problem. Hibernate 4 appears to have fundamentally changed the way you register for events and the Spring group has not yet caught up. Here's my annotation-based solution using an init method to register a listener:

@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);
    }
}

An interceptor would be another fine approach, but support for interceptors was mistakenly dropped: https://jira.springsource.org/browse/SPR-8940


The new approach is to use an Integrator to register the event listeners. Hibernate will now use service discovery for registering event listeners and here is how I got it to work using a maven archetype-webapp

create a file under META-INF/services (which should reside under your resources directory) called org.hibernate.integrator.spi.Integrator with all classes that implement the hibernate spi Interface, one line each. Short example below:

...

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
            ...
        }
    }

    ...
}

Any entity that needs to have this event registered to it must implement MyPersistableEntity (not shown here)