2011-11-08 35 views
110

我对自己在JSP Web应用程序中使用Hibernate的一些问题。休眠的openSession()VS的getCurrentSession()

  1. 应该是什么hibernate.current_session_context_class价值?

  2. 然后,将下面的语句应该使用?为什么?

    Session s = HibernateUtil.getSessionFactory().openSession(); 
    Session s = HibernateUtil.getSessionFactory().getCurrentSession() 
    
  3. 最后,哪一个更好“每个Web应用程序一个会话”或“每个请求一个会话”?

回答

122

正如在这个论坛post,1和2的相关说明。如果您将hibernate.current_session_context_class设置为线程,然后实现类似于打开会话的servlet过滤器的东西 - 那么您可以通过使用SessionFactory.getCurrentSession()访问其他任何地方的会话。

SessionFactory.openSession()始终打开,你必须关闭,一旦你与操作做一个新的会话。 SessionFactory.getCurrentSession()返回绑定到上下文的会话 - 您不需要关闭它。

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

你不应该使用one session per web app - 会话不是一个线程安全的对象 - 不能由多个线程共享。你应该总是使用“每个请求一个会话”或“每交易一个会话”

+0

非常感谢@gkamal。我查看[Open View in View](http://community.jboss.org/wiki/OpenSessionInView)文件中的代码。 (您的链接指向该文档。)作者建议使用过滤器。在他的过滤代码中,他不会调用'openSession()'或'close()'。他只调用'getCurrentSession()'。我猜他把'current_session_context'设置为'thread'。现在我想我理解'getCurrentSession()'。但是,我不知道什么时候应该使用'openSession()'。 – wannik

+4

如果您不想将会话绑定到任何上下文,您将使用OpenSession。在某些情况下,你需要一个不同的会话 - 除了绑定到上下文之外(Hibernate拦截器有一个局限性,你不能使用原始会话) - 在这种情况下,你将使用OpenSession而不是currentSession。 OpenSession创建一个新的会话,您必须明确关闭。例如,在DAO方法中,您将调用OpenSession - 使用会话并关闭它。 – gkamal

+0

am使用getCurrentSession();因为我在监听器中初始化它,而不是过滤器从您的视图中可以看到;我正在使用mvc2 jsp servlet – shareef

-4

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

会话:“对于一个请求 - 响应周期的一个会话”。您可以在请求发出时打开会话,并在完成请求过程后关闭会话。 注意: - 不要为Web应用程序使用一个会话。

13

如果我们谈论SessionFactory.openSession()

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

,如果我们谈论SessionFactory.getCurrentSession()

  • 它创建了一个新的会话,如果不存在,否则使用的是当前的休眠情况下相同的会话。
  • 您不需要刷新和关闭会话对象,它会在内部由Hibernate自动处理。
  • 在单线程环境中,它比openSession更快。
  • 您需要配置其他属性。 “hibernate.current_session_context_class”来调用getCurrentSession方法,否则会抛出异常。
0
openSession :- When you call SessionFactory.openSession, it always create new Session object afresh and give it to you. 

你需要明确冲洗和关闭这些会话对象。 由于会话对象不是线程安全的,因此您需要在多线程环境中为每个请求创建一个会话对象,并在Web应用程序中为每个请求创建一个会话。

getCurrentSession :- When you call SessionFactory. getCurrentSession, it will provide you session object which is in hibernate context and managed by hibernate internally. It is bound to transaction scope. 
When you call SessionFactory. getCurrentSession , it creates a new Session if not exists , else use same session which is in current hibernate context. It automatically flush and close session when transaction ends, so you do not need to do externally. 
If you are using hibernate in single threaded environment , you can use getCurrentSession, as it is faster in performance as compare to creating new session each time. 
You need to add following property to hibernate.cfg.xml to use getCurrentSession method. 



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