我将如何从DAO中的ServletContext获取SessionFactory [英] How would I obtain SessionFactory from the ServletContext in the DAO

查看:159
本文介绍了我将如何从DAO中的ServletContext获取SessionFactory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了这样的DAO:这是基于: Hibernate:CRUD通用DAO

  public class Dao {
SessionFactory sessionFactory;
//初始化会话工厂
public用户保存(User o){
return(User)sessionFactory.getCurrentSession()。save(o);
}

public用户获得(Long id){
return(User)sessionFactory.getCurrentSession()。get(User.class,id);
}

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

$ / code>

现在,这很好,如果我的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);




$ b

在这种情况下,我如何从DAO调用SessionFactory除了实际包装一个servletRequest到DAO中吗?

解决方案

强烈阻止存储Hibernate SessionFactory 转换为Servlet的 ServletContext 。另外,让你的DAO使用你的Hibernate Session 来代替。



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

  / ** 
*
* /
包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;
导入org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

/ **
*这是一个严格使用Hibernate 4.x库的Hibernate实用程序类。
*
* @author Buhake Sindi
* @since 26 November 2012
*
* /
public final class HibernateUtils {

private static final Logger logger = Logger.getLogger(HibernateUtils.class.getName());
private static配置配置;
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());
抛出新的ExceptionInInitializerError(e);


$ b $ **
私有构造函数
* /
private HibernateUtils(){}

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

/ **
*检索线程本地的当前会话。
*
*返回当前线程的Hibernate {@link Session}。
*当Hibernate打开一个新会话时出现问题时,引发HibernateException。
* /
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);
}
}

返回会话;

$ b $ **
*关闭Hibernate Session(从< code> getSession()< / code>会话创建
* /
public static void closeSession(){
Session session = sessionThread.get();
sessionThread.set(null);
if(session!= null&&&session; isOpen()){
session.close();
}
}

/ **
*注册一个Hibernate {@link拦截器}。
* @param interceptor
* /
public static void registerInterceptor(Interceptor interceptor){
interceptorThread.set(interceptor);
}

/ **
*获取注册的Hibernate拦截器。
* @return
* /
public static Interceptor getInterceptor(){
return interceptorThread.get();






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



我希望这有助于。


I have created a DAO like this: This is based from: 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);
    }

Now, this is all fine, if my sessionFactory is in the DAO or in other classes. But my problem is calling SessionFactory from the servletContextListener: Here is my code in the listener:

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

How would I call SessionFactory from the DAO in this case aside from actually wrapping a servletRequest inside the DAO?

解决方案

I strongly discourage storing Hibernate SessionFactory into Servlet's ServletContext. Also, have your DAO use your Hibernate Session instead.

To tackle your issue of having your Hibernate SessionFactory instantiated once, I created a singleton class to manage this:

/**
 * 
 */
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();
    }
}

And in my DAO, I just retrieve the session as HibernateUtils.getSession();. That way, my MVC application has no reference to my specific DAO implementation.

I hope this helps.

这篇关于我将如何从DAO中的ServletContext获取SessionFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆