休眠openSession()vs getCurrentSession()


130

我对在JSP Web应用程序中使用Hibernate有一些疑问。

  1. 它的价值是hibernate.current_session_context_class什么?

  2. 然后,应使用以下哪个语句?又为什么呢

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. 最后,“每个网络应用一个会话”还是“每个请求一个会话”哪个更好?

Answers:


145

如本论坛帖子所述,1和2是相关的。如果设置hibernate.current_session_context_class为线程,然后实现打开会话的servlet过滤器之类的东西,则可以使用来访问该会话SessionFactory.getCurrentSession()

SessionFactory.openSession()操作完成后,始终会打开一个新会话,您必须关闭该会话。SessionFactory.getCurrentSession()返回绑定到上下文的会话-您无需关闭它。

如果您使用Spring或EJB管理事务,则可以将它们配置为与事务一起打开/关闭会话。

您永远不要使用one session per web app-会话不是线程安全的对象-不能被多个线程共享。您应该始终使用“每个请求一个会话”或“每个事务一个会话”


非常感谢,@ gkamal。我在View文档的Open Session中查看代码。(您的链接指向该文档。)作者建议使用过滤器。在他的过滤器代码中,他不会调用openSession()close()。他只打电话getCurrentSession()。我想他要去current_session_contextthread。现在我想我明白了getCurrentSession()。但是,我不知道该何时使用openSession()
wannik

4
如果您不希望会话绑定到任何上下文,则将使用OpenSession。在某些情况下,您需要一个不同的会话-除了绑定到上下文的会话(Hibernate Interceptor有一个限制,即您不能使用原始会话)-在这些情况下,您将使用OpenSession而不是currentSession。OpenSession创建一个新的会话,您必须显式关闭它。例如,在DAO方法中,您将调用OpenSession-使用该会话并关闭它。
gkamal

我正在使用getCurrentSession(); 因为我在侦听器中初始化了它,但从您的观点来看,没有过滤器是可以的;正在使用mvc2 jsp servlet
shareef 2013年

@gkamal-我有一个有关的问题Sessions。你能帮帮我吧在- stackoverflow.com/questions/23351083/...。谢谢你和chenqui。
Erran Morad 2014年

IMO,好的做法是让每个线程都拥有自己的Session,而只有一个Session,对吗?
coderz

31

如果我们谈论SessionFactory.openSession()

  • 它总是创建一个新的Session对象。
  • 您需要显式刷新和关闭会话对象。
  • 在单线程环境中,它比getCurrentSession()慢。
  • 您无需配置任何属性即可调用此方法。

如果我们谈论SessionFactory.getCurrentSession()

  • 如果不存在,它将创建一个新的会话,否则将使用当前休眠上下文中的相同会话。
  • 您不需要刷新和关闭会话对象,Hibernate会自动在内部对其进行处理。
  • 在单线程环境中,它比openSession()更快。
  • 您需要配置其他属性。“ hibernate.current_session_context_class”调用getCurrentSession()方法,否则将引发异常。

上面的答案告诉每个Web应用程序不要使用单个会话。因此,如果我要使用getCurrentSession,它将重复使用同一会话,不是吗?
parsecer

9

openSession:当您调用时SessionFactory.openSession,它总是创建一个新Session对象并将其提供给您。

您需要显式刷新并关闭这些会话对象。

由于会话对象不是线程安全的,因此您需要在多线程环境中为每个请求创建一个会话对象,在Web应用程序中也为每个请求创建一个会话。

getCurrentSession:调用时SessionFactory.getCurrentSession,它将为您提供会话对象,该对象位于休眠上下文中,并在内部由休眠管理。它绑定到事务范围。

调用时SessionFactory.getCurrentSession,它将创建一个新的(Session如果不存在的话),否则使用当前休眠上下文中的相同会话。当事务结束时,它将自动刷新并关闭会话,因此您无需在外部进行操作。

如果您在单线程环境中使用休眠模式,则可以使用getCurrentSession,因为与每次创建新会话相比,它的性能更快。

您需要在hibernate.cfg.xml中添加以下属性才能使用getCurrentSession方法:

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>

servlet不会为每个请求打开一个新线程吗?因此,如果它是Java Web应用程序,那么它已经不是单线程环境了吗?
parsecer

0
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Parameter            |                                openSession                                 |                                          getCurrentSession                                          |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session  creation    | Always open new session                                                    | It opens a new Session if not exists , else use same session which is in current hibernate context. |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session close        | Need to close the session object once all the database operations are done | No need to close the session. Once the session factory is closed, this session object is closed.    |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Flush and close      | Need to explicity flush and close session objects                          | No need to flush and close sessions , since it is automatically taken by hibernate internally.      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Performance          | In single threaded environment , it is slower than getCurrentSession       | In single threaded environment , it is faster than openSession                                      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Configuration        | No need to configure any property to call this method                      | Need to configure additional property:                                                              |
|                      |                                                                            |  <property name=""hibernate.current_session_context_class"">thread</property>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+

-6

SessionFactory:“每个数据库每个应用程序一个SessionFactory”(例如,如果在我们的应用程序中使用3个数据库,则每个数据库需要创建sessionFactory对象,总共需要创建3个sessionFactorys;否则,如果只有一个数据库一个sessionfactory足够 )。

会话:“一个会话代表一个请求-响应周期”。您可以在请求到来时打开会话,也可以在请求过程完成后关闭会话。注意:-不要将一个会话用于Web应用程序。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.