Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单例DAO实例在HTTP事务之间保留旧的关闭会话_Java_Hibernate_Singleton_Dao - Fatal编程技术网

Java 单例DAO实例在HTTP事务之间保留旧的关闭会话

Java 单例DAO实例在HTTP事务之间保留旧的关闭会话,java,hibernate,singleton,dao,Java,Hibernate,Singleton,Dao,我试图用Hibernate实现“每个http请求一个会话”模式,它适用于第一个请求:servlet的doGet()方法打开会话,获取一些内容,然后关闭会话 但是当我刷新浏览器时,我的DAO Singleton实例(其构造函数从SessionFactory获取会话)第二次被调用,但仍然使用旧的会话对象(不再调用Singleton构造函数)。然后我得到一个“会话已关闭”错误 我猜单例实例必须在HTTP请求之间保持在缓存中,所以:如何再次调用DAO单例构造函数?(或者使用另一种优雅的解决方案来创建新的

我试图用Hibernate实现“每个http请求一个会话”模式,它适用于第一个请求:servlet的doGet()方法打开会话,获取一些内容,然后关闭会话

但是当我刷新浏览器时,我的DAO Singleton实例(其构造函数从SessionFactory获取会话)第二次被调用,但仍然使用旧的会话对象(不再调用Singleton构造函数)。然后我得到一个“会话已关闭”错误

我猜单例实例必须在HTTP请求之间保持在缓存中,所以:如何再次调用DAO单例构造函数?(或者使用另一种优雅的解决方案来创建新的SessionFactory会话对象?)

多谢各位

servlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        // Gets the session, eventually creates one
        Session s = HibernateUtil.currentSession();

        // Gets data from singleton DAO instance
        MySingletonDAO o = MySingletonDAO.getInstance();
        List<Stuff> stuff = o.getAllTheStuff();

        // send it to the view
        request.setAttribute("foo",stuff);
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(vue);
        dispatcher.forward(request, response);

    }
             /*  error handling blah blah */
    finally {
        // closing the session
        HibernateUtil.closeSession();
    }

你所要求的是没有意义的:如果在每个请求中都调用了单例的构造函数,那么它就不再是单例了。会话确实在请求结束时关闭,但DAO保留对会话的引用,而不是每次调用它时都从util类获取它

您的DAO代码应该是

public class MySingletonDAO {
    private static MySingletonDAO INSTANCE = new MySingletonDAO();
    public static MySingletonDAO getInstance() { return INSTANCE;}

    private MySingletonDAO() {
    }

    public List<Stuff> getAllTheStuff() {
        Session session = HibernateUtil.currentSession();
        try {
            session.beginTransaction();
            Query q = session.createQuery("FROM StuffDBTable");
            session.getTransaction().commit();
            return (List<Stuff>) q.list();
        }
    }
}
公共类MySingletonDAO{
私有静态MySingletonDAO实例=新的MySingletonDAO();
公共静态MySingletonDAO getInstance(){return INSTANCE;}
二等兵米辛格尔顿道(){
}
公共列表GetAllTheStaff(){
Session Session=HibernateUtil.currentSession();
试一试{
session.beginTransaction();
Query q=session.createQuery(“来自StuffDBTable”);
session.getTransaction().commit();
返回(列表)q.List();
}
}
}
也就是说,事务应该以声明方式处理,并且应该在服务层而不是DAO层处理:事务通常使用deveral DAO,DAO返回的实体应该保持管理,对这些实体的所有访问和修改都应该在事务内部进行


我强烈建议使用JavaEE容器或Spring为您处理事务和会话处理。您还应该使用标准JPA API,而不是专有的Hibernate API。

服务层是我需要的线索,我不明白为什么模型必须管理事务和会话。如果我正确地得到了您的有用指导(在浏览一点之后),它将充当Servlet和DAO方法之间的中间层,以管理事务、错误和返回对象处理等次要问题。如果可以的话,为了将来的读者,我建议以下链接帮助我了解全局:
public class HibernateUtil {

    private static final SessionFactory sessionFactory;
    public static final ThreadLocal session = new ThreadLocal();

    static {
        try {
            // Creates the SessionFactory
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (HibernateException he) {
            throw new RuntimeException("Conf problem : "+ he.getMessage(), he);
        }
    }


    public static Session currentSession() throws HibernateException {
        Session s = (Session) session.get();
        // Opens a new Session, if this Thread has none
        if (s == null || !s.isOpen() ) {
            s = sessionFactory.openSession();
            session.set(s);
        }
        return s;
    }

    public static void closeSession() throws HibernateException {
        Session s = (Session) session.get();
        session.set(null);
        if (s != null)
            s.close();
    }
}
public class MySingletonDAO {
    private static MySingletonDAO INSTANCE = new MySingletonDAO();
    public static MySingletonDAO getInstance() { return INSTANCE;}

    private MySingletonDAO() {
    }

    public List<Stuff> getAllTheStuff() {
        Session session = HibernateUtil.currentSession();
        try {
            session.beginTransaction();
            Query q = session.createQuery("FROM StuffDBTable");
            session.getTransaction().commit();
            return (List<Stuff>) q.list();
        }
    }
}