需要在选择之后关闭hibernate会话吗?

时间:2016-12-13 10:12:54

标签: java hibernate hibernate-session

如果我使用SessionFactory

private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
    public Session getSession() {
            return sessionFactory.openSession();
        }

在我的DAO课程中使用它:

public List<Entity> fetchEntities(Date fromDate, Date toDate) {
 Criteria criteria = getSession().createCriteria(Entity.class);
        criteria.add(Restrictions.between("cts", fromDate, toDate));
        criteria.addOrder(Order.desc("cts"));
        return (List<Entity>) criteria.list();
}

我需要关闭会话吗?怎么做到这一点?

3 个答案:

答案 0 :(得分:2)

public List<Entity> fetchEntities(Date fromDate, Date toDate) {
 Criteria criteria = getSession().createCriteria(Entity.class);
        criteria.add(Restrictions.between("cts", fromDate, toDate));
        criteria.addOrder(Order.desc("cts"));
        return (List<Entity>) criteria.list();
}
  

我需要关闭会话吗?怎么做得好?

如果您创建一个会话实例并为每个执行的查询关闭它,它可能会起作用,但它也可能有副作用,例如连接池瓶颈或过度使用内存。
close()释放JDBC连接并执行一些清理。

org.hibernate.Interface Session 类的Connection close()方法声明:

  

通过释放JDBC连接并清理来结束会话。

因此,您不应该为每个执行的查询打开和关闭会话 当执行与客户端请求/处理(用户,批处理...)相关的所有查询时,您应该关闭连接 当然,如果客户端请求包含单个查询,则在查询执行后关闭它是有意义的。

实际上你使用SessionFactory.openSession()来创建一个未绑定到Hibernate持久化上下文的新会话。
这意味着你必须在完成工作后明确关闭会话,否则它将永远不会被关闭 假设该方法是在客户端请求中执行的单个方法,您可以编写如下内容:

public List<Entity> fetchEntities(Date fromDate, Date toDate) {
     Session session;
     try{
        session = getSession();
        Criteria criteria = session.createCriteria(Entity.class);
        criteria.add(Restrictions.between("cts", fromDate, toDate));
        criteria.addOrder(Order.desc("cts"));
        return (List<Entity>) criteria.list();
       }
       finally {
         if (session != null) {
           session.close();
       }
}

请注意,如果您使用SessionFactory.getCurrentSession(),则无需显式关闭它,因为它会在启动和关闭事务时从创建会话的持久性上下文中获取当前会话交易完成后。

答案 1 :(得分:0)

hibernate会话的范围应该是当前的工作单元(即事务)(请记住,会话不是线程安全的)。

工厂应该在整个应用程序生命周期内保留。

另见Struggling to understand EntityManager proper use

答案 2 :(得分:-1)

没有。实际上你的网络franework(如春天)或声明式交易管理将为你做这件事。但在某些情况下,您希望自己管理会话。就像批处理一样 - 因为hibernate会话缓存不断增长