我如何从DAO中的ServletContext获取SessionFactory

时间:2015-09-25 05:45:43

标签: hibernate servlets dao sessionfactory servletcontextlistener

我创建了一个这样的DAO:它基于:Hibernate: CRUD Generic DAO

public class Dao{
    SessionFactory sessionFactory;
    // initialise session factory
    public User save(User o){
        return (User) sessionFactory.getCurrentSession().save(o);
    }

    public User get(Long id){
        return (User) sessionFactory.getCurrentSession().get(User.class, id);
    }

    public User void saveOrUpdate(User o){
                    sessionFactory.getCurrentSession().saveOrUpdate(o);
    }

现在,如果我的sessionFactory在DAO或其他类中,这一切都很好。但我的问题是从servletContextListener调用SessionFactory:这是我在侦听器中的代码:

public void contextInitialized(ServletContextEvent event)  {
    StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
    try {
        sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        event.getServletContext().setAttribute("factory", sessionFactory);
    } catch(Exception e) {
        e.printStackTrace();
        StandardServiceRegistryBuilder.destroy( registry );
    }
}

除了在DAO中实际包装servletRequest之外,在这种情况下如何从DAO调用SessionFactory?

1 个答案:

答案 0 :(得分:1)

我强烈不鼓励将Hibernate SessionFactory存储到Servlet的ServletContext中。另外,请让您的DAO使用您的休眠Session

为了解决你的Hibernate SessionFactory实例化一次的问题,我创建了一个单例类来管理它:

/**
 * 
 */
package za.co.sindi.persistence.util;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

/**
 * This is a Hibernate utility class that strictly uses the Hibernate 4.x library.
 * 
 * @author Buhake Sindi
 * @since 26 November 2012
 *
 */
public final class HibernateUtils {

    private static final Logger logger = Logger.getLogger(HibernateUtils.class.getName());
    private static Configuration configuration;
    private static SessionFactory sessionFactory;
    private static ServiceRegistry serviceRegistry;
    private static final ThreadLocal<Session> sessionThread = new ThreadLocal<Session>();
    private static final ThreadLocal<Interceptor> interceptorThread = new ThreadLocal<Interceptor>();

    static {
        try {
            configuration = new Configuration();
            serviceRegistry = new StandardServiceRegistryBuilder().build();
            sessionFactory = configuration.configure().buildSessionFactory(serviceRegistry);
        } catch (HibernateException e) {
            logger.log(Level.SEVERE, "Error intializing SessionFactory.", e.getLocalizedMessage());
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * Private constructor
     */
    private HibernateUtils() {}

    /**
     * @return the sessionFactory
     */
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * Retrieves the current session local to the thread.
     * 
     * @return Hibernate {@link Session} for current thread.
     * @throws HibernateException when Hibernate has a problem opening a new session.
     */
    public static Session getSession() {
        Session session = sessionThread.get();
        if (session == null) {
            Interceptor interceptor = getInterceptor();
            if (interceptor != null) {
                session = getSessionFactory().withOptions().interceptor(interceptor).openSession();
            } else {
                session = getSessionFactory().openSession();
            }

            if (session != null) {
                sessionThread.set(session);
            }
        }

        return session;
    }

    /**
     * Closes the Hibernate Session (created from the <code>getSession()</code> session.
     */
    public static void closeSession() {
        Session session = sessionThread.get();
        sessionThread.set(null);
        if (session != null && session.isOpen()) {
            session.close();
        }
    }

    /**
     * Registers a Hibernate {@link Interceptor}.
     * @param interceptor
     */
    public static void registerInterceptor(Interceptor interceptor) {
        interceptorThread.set(interceptor);
    }

    /**
     * Get the registered Hibernate Interceptor.
     * @return
     */
    public static Interceptor getInterceptor() {
        return interceptorThread.get();
    }
}

在我的DAO中,我只是将会话检索为HibernateUtils.getSession();。 这样,我的MVC应用程序没有引用我的特定DAO实现。

我希望这会有所帮助。