All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.krotscheck.jersey2.hibernate.factory.HibernateSessionFactoryFactory Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
/*
 * Copyright (c) 2014 Michael Krotscheck
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.krotscheck.jersey2.hibernate.factory;

import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.PerThread;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostCommitDeleteEventListener;
import org.hibernate.event.spi.PostCommitInsertEventListener;
import org.hibernate.event.spi.PostCommitUpdateEventListener;
import org.hibernate.event.spi.PostDeleteEventListener;
import org.hibernate.event.spi.PostInsertEventListener;
import org.hibernate.event.spi.PostUpdateEventListener;
import org.hibernate.event.spi.PreDeleteEventListener;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.event.spi.PreUpdateEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.hibernate.service.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import javax.inject.Inject;

/**
 * This factory provides a singleton Hibernate SessionFactory for your
 * application context. You may use this to generate your own sessions if you
 * are not in an explicit request context, however if you do so please make sure
 * to clean up after yourself and call session.close().
 *
 * Furthermore, this injector will search through the ServiceLocator context to
 * determine if there are any Hibernate Event Listeners injected from other
 * features. It will gather those and automatically register them against the
 * hibernate factory.
 *
 * @author Michael Krotscheck
 */
public final class HibernateSessionFactoryFactory
        implements Factory {

    /**
     * Logger instance.
     */
    private static Logger logger = LoggerFactory
            .getLogger(HibernateSessionFactoryFactory.class);

    /**
     * Create a new factory factory.
     *
     * @param hibernateConfig The Hibernate Config
     * @param serviceLocator  The service locator from which to resolve event
     *                        handlers.
     */
    @Inject
    public HibernateSessionFactoryFactory(final Configuration hibernateConfig,
                                          final ServiceLocator serviceLocator) {
        this.configuration = hibernateConfig;
        this.locator = serviceLocator;
    }

    /**
     * Injected hibernate configuration.
     */
    private Configuration configuration;

    /**
     * The service locator.
     */
    private ServiceLocator locator;

    /**
     * Provide a singleton instance of the hibernate session factory.
     *
     * @return A session factory.
     */
    @Override
    public SessionFactory provide() {
        logger.trace("Creating hibernate session factory.");

        // Build the service registry.
        ServiceRegistry registry = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties())
                .build();

        SessionFactory factory = configuration.buildSessionFactory(registry);

        // Register our event listeners.
        injectEventListeners(((SessionFactoryImpl) factory)
                .getServiceRegistry());

        return factory;
    }

    /**
     * Dispose of the hibernate session.
     *
     * @param sessionFactory The session to dispose.
     */
    @Override
    public void dispose(final SessionFactory sessionFactory) {
        if (sessionFactory != null && !sessionFactory.isClosed()) {
            logger.info("Disposing of hibernate session factory.");
            sessionFactory.close();
        }
    }

    /**
     * This method automatically adds discovered hibernate event listeners into
     * the hibernate service registry.
     *
     * @param registry The service registry.
     */
    private void injectEventListeners(final ServiceRegistry registry) {

        EventListenerRegistry eventRegistry = registry
                .getService(EventListenerRegistry.class);

        List postInsertEvents = locator
                .getAllServices(PostInsertEventListener.class);
        for (PostInsertEventListener piEventListener : postInsertEvents) {
            logger.trace("Registering PostInsert: " + piEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.POST_INSERT,
                    piEventListener);
        }

        List postUpdateEvents = locator
                .getAllServices(PostUpdateEventListener.class);
        for (PostUpdateEventListener puEventListener : postUpdateEvents) {
            logger.trace("Registering PostUpdate: " + puEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.POST_UPDATE,
                    puEventListener);
        }

        List postDeleteEvents = locator
                .getAllServices(PostDeleteEventListener.class);
        for (PostDeleteEventListener pdEventListener : postDeleteEvents) {
            logger.trace("Registering PostDelete: " + pdEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.POST_DELETE,
                    pdEventListener);
        }

        List preInsertEvents = locator
                .getAllServices(PreInsertEventListener.class);
        for (PreInsertEventListener piEventListener : preInsertEvents) {
            logger.trace("Registering PreInsert: " + piEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.PRE_INSERT,
                    piEventListener);
        }

        List preUpdateEvents = locator
                .getAllServices(PreUpdateEventListener.class);
        for (PreUpdateEventListener puEventListener : preUpdateEvents) {
            logger.trace("Registering PreUpdate: " + puEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.PRE_UPDATE,
                    puEventListener);
        }

        List preDeleteEvents = locator
                .getAllServices(PreDeleteEventListener.class);
        for (PreDeleteEventListener pdEventListener : preDeleteEvents) {
            logger.trace("Registering PreDelete: " + pdEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.PRE_DELETE,
                    pdEventListener);
        }

        List pciEvents = locator
                .getAllServices(PostCommitInsertEventListener.class);
        for (PostCommitInsertEventListener cpiEventListener : pciEvents) {
            logger.trace("Registering PostCommitInsert: " + cpiEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.POST_COMMIT_INSERT,
                    cpiEventListener);
        }

        List pcuEvents = locator
                .getAllServices(PostCommitUpdateEventListener.class);
        for (PostCommitUpdateEventListener cpuEventListener : pcuEvents) {
            logger.trace("Registering PostCommitUpdate: " + cpuEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.POST_COMMIT_UPDATE,
                    cpuEventListener);
        }

        List pcdEvents = locator
                .getAllServices(PostCommitDeleteEventListener.class);
        for (PostCommitDeleteEventListener cpdEventListener : pcdEvents) {
            logger.trace("Registering PostCommitDelete: " + cpdEventListener
                    .getClass().getCanonicalName());
            eventRegistry.appendListeners(EventType.POST_COMMIT_DELETE,
                    cpdEventListener);
        }
    }

    /**
     * HK2 Binder for our injector context.
     */
    public static final class Binder extends AbstractBinder {

        @Override
        protected void configure() {
            bindFactory(HibernateSessionFactoryFactory.class)
                    .to(SessionFactory.class)
                    .in(PerThread.class);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy