Hibernate openSession () vs getCurrentSession ()


130

Ich habe einige Fragen zur Verwendung von Hibernate in JSP-Webanwendungen.

  1. Wofür sollte der Wert sein hibernate.current_session_context_class?

  2. Welche der folgenden Aussagen sollte dann verwendet werden? Und warum?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
    
  3. Welches ist besser "eine Sitzung pro Web-App" oder "eine Sitzung pro Anfrage"?

Antworten:


145

Wie in diesem Forum erklärten Post , 1 und 2 betreffen. Wenn Sie hibernate.current_session_context_classThread festlegen und dann so etwas wie einen Servlet-Filter implementieren, der die Sitzung öffnet, können Sie mit der Taste auf diese Sitzung an einer anderen Stelle zugreifen SessionFactory.getCurrentSession().

SessionFactory.openSession()Öffnet immer eine neue Sitzung, die Sie schließen müssen, wenn Sie mit den Vorgängen fertig sind. SessionFactory.getCurrentSession()Gibt eine an einen Kontext gebundene Sitzung zurück - Sie müssen diese nicht schließen.

Wenn Sie Spring oder EJBs zum Verwalten von Transaktionen verwenden, können Sie diese so konfigurieren, dass Sitzungen zusammen mit den Transaktionen geöffnet / geschlossen werden.

Sie sollten niemals verwenden one session per web app- Sitzung ist kein threadsicheres Objekt - kann nicht von mehreren Threads gemeinsam genutzt werden. Sie sollten immer "eine Sitzung pro Anforderung" oder "eine Sitzung pro Transaktion" verwenden.


Vielen Dank, @gkamal. Ich sehe mir den Code im Dokument Open Session in View an . (Ihr Link verweist auf diese Dokumente.) Der Autor schlägt die Verwendung eines Filters vor. In seinem Filtercode ruft er nicht openSession()oder an close(). Er ruft nur an getCurrentSession(). Ich denke, er setzt current_session_contextauf thread. Jetzt glaube ich zu verstehen getCurrentSession(). Ich weiß jedoch nicht, wann ich verwenden soll openSession().
Möchte

4
Sie verwenden OpenSession, wenn Sie nicht möchten, dass die Sitzung an einen Kontext gebunden wird. In einigen Situationen benötigen Sie eine andere Sitzung als eine an den Kontext gebundene (Hibernate Interceptors haben die Einschränkung, dass Sie die ursprüngliche Sitzung nicht verwenden können). In diesen Fällen verwenden Sie OpenSession anstelle von currentSession. OpenSession erstellt eine neue Sitzung, die Sie explizit schließen müssen. Beispielsweise rufen Sie in einer DAO-Methode OpenSession auf - verwenden Sie die Sitzung und schließen Sie sie.
Gkamal

verwende getCurrentSession (); weil ich es im Listener nicht gefiltert habe, ist dies aus Ihrer Sicht in Ordnung; Ich benutze MVC2 JSP Servlet
Shareef

@gkamal - Ich habe eine Frage im Zusammenhang mit Sessions. Können Sie mir bitte dabei helfen unter - stackoverflow.com/questions/23351083/… . Danke und Chenqui.
Erran Morad

IMO, es ist eine gute Praxis, jeden Thread seine eigene Sitzung und nur eine Sitzung abhalten zu lassen, oder?
Coderz

31

Wenn wir über SessionFactory.openSession () sprechen

  • Es wird immer ein neues Sitzungsobjekt erstellt.
  • Sie müssen Sitzungsobjekte explizit leeren und schließen.
  • In einer Umgebung mit einem Thread ist es langsamer als getCurrentSession ().
  • Sie müssen keine Eigenschaft konfigurieren, um diese Methode aufzurufen.

Und wenn wir über SessionFactory.getCurrentSession () sprechen

  • Wenn keine neue Sitzung vorhanden ist, wird eine neue Sitzung erstellt. Andernfalls wird dieselbe Sitzung verwendet, die sich im aktuellen Ruhezustand befindet.
  • Sie müssen keine Sitzungsobjekte leeren und schließen, dies wird automatisch von Hibernate intern erledigt.
  • In einer Single-Thread-Umgebung ist es schneller als openSession ().
  • Sie müssen zusätzliche Eigenschaften konfigurieren. "hibernate.current_session_context_class", um die Methode getCurrentSession () aufzurufen, andernfalls wird eine Ausnahme ausgelöst.

Die obige Antwort besagt, dass keine einzige Sitzung pro Webanwendung verwendet werden soll. Wenn ich also verwenden getCurrentSessionwürde, würde es dieselbe Sitzung wiederverwenden, nicht wahr?
Parsecer

9

openSession: Wenn Sie anrufen SessionFactory.openSession, wird immer ein neues SessionObjekt erstellt und Ihnen übergeben.

Sie müssen diese Sitzungsobjekte explizit leeren und schließen.

Da Sitzungsobjekte nicht threadsicher sind, müssen Sie ein Sitzungsobjekt pro Anforderung in einer Umgebung mit mehreren Threads und eine Sitzung pro Anforderung auch in Webanwendungen erstellen.

getCurrentSession: Wenn Sie aufrufen SessionFactory.getCurrentSession, erhalten Sie ein Sitzungsobjekt, das sich im Ruhezustand befindet und intern im Ruhezustand verwaltet wird. Es ist an den Transaktionsumfang gebunden.

Wenn Sie aufrufen SessionFactory.getCurrentSession, wird eine neue SessionSitzung erstellt, wenn diese nicht vorhanden ist. Andernfalls wird dieselbe Sitzung verwendet, die sich im aktuellen Ruhezustand befindet. Die Sitzung wird automatisch geleert und geschlossen, wenn die Transaktion endet, sodass Sie sie nicht extern ausführen müssen.

Wenn Sie den Ruhezustand in einer Single-Thread-Umgebung verwenden, können Sie ihn verwenden getCurrentSession, da er im Vergleich zum Erstellen einer neuen Sitzung jedes Mal schneller ist.

Sie müssen folgende Eigenschaft hinzufügen hibernate.cfg.xml zu verwenden getCurrentSessionMethode:

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

Öffnet ein Servlet nicht für jede Anforderung einen neuen Thread? Wenn es sich also um eine Java-Webanwendung handelt, handelt es sich bereits nicht um eine Single-Thread-Umgebung?
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: "Eine SessionFactory pro Anwendung pro Datenbank" (z. B. wenn Sie in unserer Anwendung 3 Datenbanken verwenden, müssen Sie ein SessionFactory-Objekt pro Datenbank erstellen, insgesamt müssen Sie 3 sessionFactorys erstellen, oder wenn Sie nur eine DataBase One-Sessionfactory haben reicht ).

Sitzung: "Eine Sitzung für einen Anforderungs- / Antwortzyklus". Sie können die Sitzung öffnen, wenn die Anforderung eingegangen ist, und die Sitzung nach Abschluss des Anforderungsprozesses schließen. Hinweis: - Verwenden Sie keine Sitzung für Webanwendungen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.