Hibernate openSession () vs getCurrentSession ()

130

Tengo algunas preguntas sobre el uso de Hibernate en la aplicación web JSP.

  1. ¿Cuál debería ser el valor hibernate.current_session_context_class?

  2. Entonces, ¿cuál de las siguientes afirmaciones debe usarse? ¿Y por qué?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. Por último, ¿cuál es mejor "una sesión por aplicación web" o "una sesión por solicitud"?

wannik
fuente

Respuestas:

145

Como se explica en esta publicación del foro , 1 y 2 están relacionados. Si configura hibernate.current_session_context_classun subproceso y luego implementa algo como un filtro de servlet que abre la sesión, puede acceder a esa sesión en cualquier otro lugar utilizando el SessionFactory.getCurrentSession().

SessionFactory.openSession()siempre abre una nueva sesión que debe cerrar una vez que haya terminado con las operaciones. SessionFactory.getCurrentSession()devuelve una sesión vinculada a un contexto; no es necesario que cierre esto.

Si está utilizando Spring o EJB para administrar transacciones, puede configurarlas para abrir / cerrar sesiones junto con las transacciones.

Nunca debe usar one session per web app, la sesión no es un objeto seguro para subprocesos, no puede ser compartida por múltiples subprocesos. Siempre debe usar "una sesión por solicitud" o "una sesión por transacción"

gkamal
fuente
Muchas gracias, @gkamal. Miro el código en Abrir sesión en Ver documento. (Su enlace apunta a esos documentos). El autor sugiere el uso de filtro. En su código de filtro, no llama openSession()o close(). El solo llama getCurrentSession(). Supongo que se pone current_session_contexta ello thread. Ahora creo que entiendo getCurrentSession(). Sin embargo, no sé cuándo debo usar openSession().
wannik
44
Utilizará OpenSession si no desea que la sesión esté vinculada a ningún contexto. Hay algunas situaciones en las que necesitaría una sesión diferente, distinta de una vinculada al contexto (los Interceptores Hibernate tienen una limitación de que no puede usar la sesión original), en esos casos usaría OpenSession en lugar de currentSession. OpenSession crea una nueva sesión que debe cerrar explícitamente. Por ejemplo, en un método DAO llamará a OpenSession: use la sesión y ciérrela.
gkamal
estoy usando getCurrentSession (); porque lo inicialicé en oyente no filtro está bien desde su punto de vista; estoy usando el servlet mvc2 jsp
shareef
@gkamal - Tengo una pregunta relacionada con Sessions. ¿Me pueden ayudar con esto en stackoverflow.com/questions/23351083/… . Gracias y chenqui.
Erran Morad
En mi opinión, es una buena práctica dejar que cada hilo tenga su propia sesión, y solo una sesión, ¿verdad?
coderz
31

Si hablamos de SessionFactory.openSession ()

  • Siempre crea un nuevo objeto de sesión.
  • Debe vaciar y cerrar explícitamente los objetos de sesión.
  • En un entorno de subproceso único, es más lento que getCurrentSession ().
  • No necesita configurar ninguna propiedad para llamar a este método.

Y si hablamos de SessionFactory.getCurrentSession ()

  • Crea una nueva sesión si no existe, de lo contrario usa la misma sesión que está en el contexto de hibernación actual.
  • No necesita vaciar y cerrar objetos de sesión, Hibernate se encargará automáticamente de ellos internamente.
  • En un entorno de subproceso único, es más rápido que openSession ().
  • Necesita configurar una propiedad adicional. "hibernate.current_session_context_class" para llamar al método getCurrentSession (), de lo contrario arrojará una excepción.
Ramu Agrawal
fuente
La respuesta anterior le dice que no use una sola sesión por aplicación web. Por lo tanto, si tuviera que usar getCurrentSession, reutilizaría la misma sesión, ¿no?
analizador
9

openSession: Cuando llamas SessionFactory.openSession, siempre crea un nuevo Sessionobjeto y te lo da.

Debe vaciar y cerrar explícitamente estos objetos de sesión.

Como los objetos de sesión no son seguros para subprocesos, debe crear un objeto de sesión por solicitud en un entorno de subprocesos múltiples y también una sesión por solicitud en aplicaciones web.

getCurrentSession: Cuando llame SessionFactory.getCurrentSession, le proporcionará un objeto de sesión que se encuentra en contexto de hibernación y administrado por hibernate internamente. Está sujeto al alcance de la transacción.

Cuando llama SessionFactory.getCurrentSession, crea un nuevo Sessionsi no existe, de lo contrario use la misma sesión que está en el contexto de hibernación actual. Se descarga y cierra la sesión automáticamente cuando finaliza la transacción, por lo que no es necesario que lo haga externamente.

Si está utilizando hibernación en un entorno de subproceso único, puede usarlo getCurrentSession, ya que es más rápido en rendimiento en comparación con la creación de una nueva sesión cada vez.

Debe agregar la siguiente propiedad a hibernate.cfg.xml para usar el getCurrentSessionmétodo:

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>
Neeraj Gahlawat
fuente
¿Un servlet no abre un nuevo hilo para cada solicitud? Por lo tanto, si se trata de una aplicación web Java, ¿ya no es un entorno de subproceso único?
analizador
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
fuente
-6

SessionFactory: "One SessionFactory por aplicación por DataBase" (por ejemplo, si usa 3 DataBase's en nuestra aplicación, debe crear un objeto sessionFactory por cada DB, totalmente necesita crear 3 sessionFactorys. O bien si solo tiene una DataBase One sessionfactory es suficiente ).

Sesión: "Una sesión para un ciclo de solicitud-respuesta". puede abrir la sesión cuando llegó la solicitud y puede cerrar la sesión después de completar el proceso de solicitud. Nota: -No use una sesión para la aplicación web.

swamy
fuente