Hibernate openSession () vs getCurrentSession ()

130

J'ai quelques questions sur l'utilisation d'Hibernate dans l'application Web JSP.

  1. Quelle devrait être la valeur hibernate.current_session_context_class?

  2. Alors, laquelle des affirmations suivantes doit être utilisée? Et pourquoi?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. Enfin, lequel est le meilleur "une session par application Web" ou "une session par demande"?

wannik
la source

Réponses:

145

Comme expliqué dans ce message du forum , 1 et 2 sont liés. Si vous définissez hibernate.current_session_context_classsur thread, puis implémentez quelque chose comme un filtre de servlet qui ouvre la session, vous pouvez accéder à cette session n'importe où ailleurs en utilisant le SessionFactory.getCurrentSession().

SessionFactory.openSession()ouvre toujours une nouvelle session que vous devez fermer une fois que vous avez terminé les opérations. SessionFactory.getCurrentSession()renvoie une session liée à un contexte - vous n'avez pas besoin de la fermer.

Si vous utilisez Spring ou EJB pour gérer les transactions, vous pouvez les configurer pour ouvrir / fermer des sessions avec les transactions.

Vous ne devez jamais utiliser one session per web app- la session n'est pas un objet thread-safe - ne peut pas être partagée par plusieurs threads. Vous devez toujours utiliser "une session par demande" ou "une session par transaction"

gkamal
la source
Merci beaucoup, @gkamal. Je regarde le code dans Open Session in View document. (Votre lien pointe vers ces documents.) L'auteur suggère l'utilisation d'un filtre. Dans son code de filtre, il n'appelle pas openSession()ou close(). Il appelle seulement getCurrentSession(). Je suppose qu'il fixe current_session_contextà thread. Maintenant, je pense que je comprends getCurrentSession(). Cependant, je ne sais pas quand dois-je utiliser openSession().
wannik
4
Vous utiliserez OpenSession si vous ne souhaitez pas que la session soit liée à un contexte. Il existe certaines situations où vous auriez besoin d'une session différente - autre qu'une session liée au contexte (les intercepteurs Hibernate ont une limitation selon laquelle vous ne pouvez pas utiliser la session d'origine) - dans ces cas, vous utiliseriez OpenSession au lieu de currentSession. OpenSession crée une nouvelle session que vous devez fermer explicitement. Par exemple, dans une méthode DAO, vous appellerez OpenSession - utilisez la session et fermez-la.
gkamal
j'utilise getCurrentSession (); parce que je l'ai initialisé dans l'auditeur et non le filtre est-ce correct de votre point de vue; j'utilise mvc2 jsp servlet
shareef
@gkamal - J'ai une question à propos de Sessions. Pouvez-vous s'il vous plaît m'aider avec - stackoverflow.com/questions/23351083/… . Merci et chenqui.
Erran Morad
OMI, il est bon de laisser chaque fil de discussion tenir sa propre session, et une seule session, non?
coderz le
31

Si nous parlons de SessionFactory.openSession ()

  • Il crée toujours un nouvel objet Session.
  • Vous devez vider et fermer explicitement les objets de session.
  • Dans un environnement à thread unique, il est plus lent que getCurrentSession ().
  • Vous n'avez pas besoin de configurer de propriété pour appeler cette méthode.

Et si nous parlons de SessionFactory.getCurrentSession ()

  • Il crée une nouvelle session s'il n'existe pas, sinon utilise la même session qui se trouve dans le contexte de mise en veille prolongée actuel.
  • Vous n'avez pas besoin de vider et de fermer les objets de session, cela sera automatiquement pris en charge par Hibernate en interne.
  • Dans un environnement à thread unique, il est plus rapide que openSession ().
  • Vous devez configurer une propriété supplémentaire. "hibernate.current_session_context_class" pour appeler la méthode getCurrentSession (), sinon il lèvera une exception.
Ramu Agrawal
la source
La réponse ci-dessus indique de ne pas utiliser une seule session par application Web. Ainsi, si je devais utiliser getCurrentSession, cela réutiliserait la même session, n'est-ce pas?
parsecer
9

openSession: Lorsque vous appelez SessionFactory.openSession, il crée toujours un nouvel Sessionobjet et vous le donne.

Vous devez explicitement vider et fermer ces objets de session.

Comme les objets de session ne sont pas thread-safe, vous devez créer un objet de session par demande dans un environnement multi-thread et une session par demande dans les applications Web également.

getCurrentSession: Lorsque vous appelez SessionFactory.getCurrentSession, il vous fournira un objet de session qui est dans un contexte de mise en veille prolongée et géré par hibernate en interne. Il est lié à la portée de la transaction.

Lorsque vous appelez SessionFactory.getCurrentSession, il en crée un nouveau Sessions'il n'existe pas, sinon utilisez la même session qui se trouve dans le contexte de mise en veille prolongée actuel. Il vide et ferme automatiquement la session lorsque la transaction se termine, vous n'avez donc pas besoin de le faire en externe.

Si vous utilisez la mise en veille prolongée dans un environnement à thread unique, vous pouvez l'utiliser getCurrentSession, car ses performances sont plus rapides que la création d'une nouvelle session à chaque fois.

Vous devez ajouter la propriété suivante à hibernate.cfg.xml pour utiliser la getCurrentSessionméthode:

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>
Neeraj Gahlawat
la source
Un servlet n'ouvre-t-il pas un nouveau thread pour chaque requête? Donc, s'il s'agit d'une webapp Java, ce n'est déjà pas un environnement monothread?
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>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
Joby Wilson Mathews
la source
-6

SessionFactory: "Une SessionFactory par application par DataBase" (par exemple, si vous utilisez 3 DataBase dans notre application, vous devez créer un objet sessionFactory pour chaque DB, totalement vous devez créer 3 sessionFactorys. Ou bien si vous n'avez qu'une DataBase One sessionfactory est assez ).

Session: "Une session pour un cycle demande-réponse". vous pouvez ouvrir la session lorsque la demande est arrivée et vous pouvez fermer la session une fois le processus de demande terminé. Remarque: -N'utilisez pas une seule session pour l'application Web.

swamy
la source