简体   繁体   English

使用Java Hibernate进行会话管理

[英]Session Management with Java Hibernate

I have a Hibernate-based platform, built from stateless servlets (one is used to register a user and the rest to query the db). 我有一个基于Hibernate的平台,它是从无状态servlet构建的(一个用于注册用户,其余用于查询db)。

I'm using Hibernate's sessions as follows: 我正在使用Hibernate的会话,如下所示:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
if ((null == session) || (session.isOpen() == false)) {
  session = HibernateUtil.getSessionFactory().openSession();
}

Currently I do not close the session at the end of the servlet in order to avoid openSession() call (trying to use opened sessions if possible). 当前,为了避免openSession()调用,我不关闭servlet末尾的会话(如果可能,尝试使用打开的会话)。

What's the best practice ? 最佳做法是什么? when am I supposed to close these sessions ? 我应该什么时候结束这些会议?

Can you please give an example ? 你能举个例子吗?

Thanks in advance ! 提前致谢 !

The best practice is in most cases session-per-request. 最佳做法是在大多数情况下按请求进行会话。 That is, open a session in the beginning of handling a request, and close it in the end. 即,在处理请求的开始处打开一个会话,然后在结束时将其关闭。 You can do that in a Servlet Filter , for example. 例如,您可以在Servlet Filter执行此操作。

Having one session for the entire application is bad, because it will accumulate a lot of entities in its 1st level cache, which is a memory leak. 整个应用程序只有一个会话是不好的,因为它将在其一级缓存中积累大量实体,这是内存泄漏。 It may also produce undeterministic results when multiple clients use it at the same time. 当多个客户端同时使用它时,它可能还会产生不确定的结果。

Your code, however, is not using one session for the entire application - it is using the "current session" concept, which opens a session and stores it in a context (a ThreadLocal for example). 但是,您的代码并未针对整个应用程序使用一个会话-它使用的是“当前会话”概念,该概念打开一个会话并将其存储在上下文中(例如ThreadLocal )。 But if you don't close it, it will stay there forever. 但是,如果不关闭它,它将永远存在。 Plus, it will cause the same problems as described above, because threads are reused in a web application, and a new request will get an old, unclosed session at some point. 另外,它将引起与上述相同的问题,因为线程在Web应用程序中被重用,并且新请求在某个时候将获得旧的,未关闭的会话。

Its always better to open a new session for every request, and close the session once the request is processed. 最好为每个请求打开一个新会话,并在处理完请求后关闭该会话。 Like 喜欢

Session session = HibernateUtil.getSessionFactory().openSession();

instead of 代替

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

If we use the getCurrentSession() method , tansaction.commit() / rollback() closes the connection. 如果我们使用getCurrentSession()方法,则tansaction.commit()/ rollback()将关闭连接。

The best is to manage a hibernate session is to open a new session for every request. 最好的方法是管理休眠会话,就是为每个请求打开一个新会话。 It all depends on how you obtain the session. 这完全取决于您如何获得会话。

  • if you use sessionFactory.getCurrentSession(), you'll obtain a "current session" which is bound to the lifecycle of the transaction and will be automatically flushed and closed when the transaction ends (commit or rollback) 如果使用sessionFactory.getCurrentSession(),则将获得绑定到事务生命周期的“当前会话”,并在事务结束(提交或回滚)时自动刷新并关闭它
  • if you decide to use sessionFactory.openSession(), you'll have to manage the session yourself and to flush and close it "manually". 如果决定使用sessionFactory.openSession(),则必须自己管理会话并“手动”刷新并关闭它。
 if (!session.isOpen()) { session = session.getSessionFactory().openSession(); session.beginTransaction(); } 

I better recommend you to use spring framework. 我最好建议您使用spring框架。 Cause in spring you can use @Transactional at method level and session will be automatically created and closed by transaction manager (unless you are using any open session in view interceptor) using AOP which is internally handled by framework. 因为在春季,您可以在方法级别使用@Transactional ,并且会话将由事务管理器自动创建和关闭(除非您在视图拦截器中使用任何打开的会话)并使用由框架内部处理的AOP

@Autowired
EntityManager em;

@Transactinal
void save(User user){
   em.persist(user);
}

thats all.spring is fun :D 多数民众赞成在所有的春天很有趣:D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM