Event Listener Registration

Posted by    |      

4.0 changes the way event listeners get registered to leverage some added capabilities, namely services and integrators. I won't get into services too much as they are covered elsewhere. But lets start with the notion of an Integrator.

Integrator contract

Specifically, we are talking about the org.hibernate.integrator.spi.Integrator interface. The idea behind an org.hibernate.integrator.spi.Integrator is to provide a simple means to allow developers to hook into the process of building a functioning SessionFactory. A standard service provided by Hibernate is the ability to discover org.hibernate.integrator.spi.Integrator implementations by utilizing the Java java.util.ServiceLoader mechanism. Developers simply define a file named /META-INF/services/org.hibernate.integrator.spi.Integrator and make it available on the classpath. Essentially, the content of this file is one or more fully-qualified org.hibernate.integrator.spi.Integrator implementation class names, one per line each. Please see the java.util.ServiceLoader JavaDocs for the complete spec of the allowed syntax of content in this file.

The org.hibernate.integrator.spi.Integrator interface defines 2 methods of interest:

public interface Integrator {
    /**
     * Perform integration.
     *
     * @param configuration The configuration used to create the session factory
     * @param sessionFactory The session factory being created
     * @param serviceRegistry The session factory's service registry
     */
    public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry);

    /**
     * Tongue-in-cheek name for a shutdown callback.
     *
     * @param sessionFactory The session factory being closed.
     * @param serviceRegistry That session factory's service registry
     */
    public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry);

    /** 
     * Ignore this form!  Just do nothing in impl.  It uses the new metamodel api slated for completion in 5.0
     */
    public void integrate(MetadataImplementor metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry );
}

The method integrate allows us to hook into the building process; disintegrate allows us to hook into a SessionFactory shutting down.

Registration

Hibernate itself has a few implementations of the org.hibernate.integrator.spi.Integrator interface that perform event listener registration that might be good to look at for reference.

The general process for registering listeners is as follows

    public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
        // As you might expect, an EventListenerRegistry is the place with which event listeners are registered  It is a service
        // so we look it up using the service registry
        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService( EventListenerRegistry.class );

        // If you wish to have custom determination and handling of "duplicate" listeners, you would have to add an implementation
        // of the org.hibernate.event.service.spi.DuplicationStrategy contract like this
        eventListenerRegistry.addDuplicationStrategy( myDuplicationStrategy );

        // EventListenerRegistry defines 3 ways to register listeners:
        //     1) This form overrides any existing registrations with 
        eventListenerRegistry.setListeners( EventType.AUTO_FLUSH, myCompleteSetOfListeners );
        //     2) This form adds the specified listener(s) to the beginning of the listener chain
        eventListenerRegistry.prependListeners( EventType.AUTO_FLUSH, myListenersToBeCalledFirst );
        //     3) This form adds the specified listener(s) to the end of the listener chain
        eventListenerRegistry.appendListeners( EventType.AUTO_FLUSH, myListenersToBeCalledLast );
    }

Back to top