使用Java Hibernate进行会话管理
我有一个基于Hibernate的平台,由无状态servlet构建(一个用于注册用户,其余用于查询数据库)。
我正在使用Hibernate的会话如下:
Session session = HibernateUtil.getSessionFactory().getCurrentSession(); if ((null == session) || (session.isOpen() == false)) { session = HibernateUtil.getSessionFactory().openSession(); }
目前我没有关闭servlet末尾的会话,以避免openSession()
调用(尽可能尝试使用打开的会话)。
什么是最佳做法? 什么时候我应该关闭这些会议?
你能举个例子吗?
提前致谢 !
在大多数情况下,最佳做法是按请求进行会话。 也就是说,在处理请求的开始时打开一个会话,最后将其关闭。 例如,您可以在Servlet Filter
执行此操作。
对整个应用程序进行一次会话是不好的,因为它会在其第一级缓存中累积许多实体,这是一个内存泄漏。 当多个客户端同时使用它时,它也可能产生不确定的结果。
但是,您的代码并未对整个应用程序使用一个会话 – 它使用“当前会话”概念,该概念打开会话并将其存储在上下文中(例如, ThreadLocal
)。 但如果你不关闭它,它将永远留在那里。 此外,它将导致与上述相同的问题,因为线程在Web应用程序中重用,并且新请求将在某个时刻获得旧的,未闭合的会话。
最好为每个请求打开一个新会话,并在处理请求后关闭会话。 喜欢
Session session = HibernateUtil.getSessionFactory().openSession();
代替
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
如果我们使用getCurrentSession()方法,tansaction.commit()/ rollback()将关闭连接。
最好的是管理一个hibernate会话就是为每个请求打开一个新的会话。 这一切都取决于你如何获得会话。
- 如果你使用sessionFactory.getCurrentSession(),你将获得一个绑定到事务生命周期的“当前会话”,并在事务结束时自动刷新和关闭(提交或回滚)
- 如果您决定使用sessionFactory.openSession(),则必须自己管理会话并“手动”刷新和关闭它。
if (!session.isOpen()) { session = session.getSessionFactory().openSession(); session.beginTransaction(); }
我建议你使用spring框架。 在Spring中,您可以在方法级别使用@Transactional
,并且会话将由事务管理器自动创建和关闭(除非您在视图拦截器中使用任何打开的会话)使用由框架内部处理的AOP
。
@Autowired EntityManager em; @Transactinal void save(User user){ em.persist(user); }
那就是all.spring很有趣:D