2010-03-07 12 views
9

He hecho bastante investigación sobre esto sin suerte, pero todas las respuestas tienden a apuntar hacia la configuración de contexto de la sesión en el archivo de configuración. Lo que es extraño es que recibo una conexión de sesión la primera vez que llego a la página (y, por lo tanto, un conjunto de resultados exitoso), pero cuando recargo obtengo la siguiente excepción: org.hibernate.SessionException: ¡La sesión está cerrada!Tiene un problema con org.hibernate.SessionException: ¡la sesión está cerrada! en Hibernate

Éstos son mis ajustes de configuración que no están relacionados con DB cadena de conexión:

<property name="hibernate.show_sql">false</property> 
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>   
<property name="hibernate.current_session_context_class">thread</property> 
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 
<property name="hibernate.cache.use_query_cache">false</property> 
<property name="hibernate.cache.use_minimal_puts">false</property> 

Aquí es un ejemplo de una llamada que hago que produce la situación que he descrito anteriormente.

public T get(int id) { 
    session.beginTransaction(); 
    T type; 
    try { 
     type = getTypeClass().cast(session.get(getTypeClass(), id)); 
    } catch (ClassCastException classCastException) { 
     throw new ClassCastException(classCastException.getMessage()); 
    } 
    session.getTransaction().commit(); 
    return type; 
} 

La referencia de la variable de sesión es un campo estático que contiene la sesión actual. Todos los detalles de conexión de la sesión son el manual de referencia del libro de texto. Por ejemplo, aquí está mi Hibernate utilidad sesión:

import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 

public class HibernateSessionFactoryUtil { 

    private static final SessionFactory sessionFactory = buildSessionFactory(); 

    private static SessionFactory buildSessionFactory() { 
     try { 
      return new Configuration().configure().buildSessionFactory(); 
     } catch (Throwable ex) { 
      System.err.println("Initial SessionFactory creation failed." + ex); 
      throw new ExceptionInInitializerError(ex); 
     } 
    } 

    public static SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 
} 
+0

¿Tiene alguna implementación para cerrar/matar la sesión? –

Respuesta

8

Cuando se obtiene una sesión con sessionFactory.getCurrentSession(), la sesión se vacía y se cierra automáticamente cuando se compromete la transacción (ver Sessions and transactions para más detalles sobre esto). Entonces, aquí sospecho que 1. usted obtiene la Sesión de una vez por todas (esto explicaría por qué funciona la primera llamada y por qué las siguientes llamadas fallan) lo cual es incorrecto y 2. parece que usa la sesión sesión-por-operación patrón que es aún peor.

En una aplicación web, se debe utilizar una estrategia sesión-por-petición que significa que "un único modo y de una sola transacción de base de datos implementan el procesamiento de un evento de solicitud en particular". De nuevo, consulte el documento Sessions and transactions.

Y si desea eliminar la demarcación de transacción de su código de acceso a datos, puede usar un interceptor para iniciar una transacción de base de datos al comienzo de cada solicitud y enviarla al final de la solicitud. Eche un vistazo a Open Session in View para una implementación de este patrón (con un ejemplo de DAO que demuestre los beneficios).

+0

El problema con todo esto es: 1) La documentación de referencia utiliza un ejemplo básico que inmediatamente le dicen que después es incorrecto para los escenarios de producción (dejando mucho que desear con respecto a los escenarios comunes). 2) Las transacciones son casi siempre operativas, pero la documentación muestra una transacción por sesión por solicitud. ¿Desde cuándo alguien usa una transacción para un alcance de solicitud completo? Es posible que tenga tres transacciones separadas que necesita revertir durante la solicitud. Esta es un área donde Hibernate necesita hacer un mejor trabajo con la documentación. –

+0

Al final, el problema estaba relacionado con la forma en que manejaba la referencia de la variable de sesión. Probablemente moveré el manejo de la sesión de apertura/cierre en un filtro, y luego administraré las transacciones individuales por operación (o conjunto de operaciones). –

+0

@ hal10001 No estoy de acuerdo en que las transacciones sean casi siempre operativas, ** no ** desea comprometer la "mitad de una solicitud" (la sesión-por-operación no se llama antipatrón), usando una transacción por solicitud es el camino a seguir. –

Cuestiones relacionadas