2011-11-08 34 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>