2011-09-02 27 views
20

Estoy escribiendo un proyecto simple, una aplicación comercial escrita en Swing, usando Hibernate para back-end. Vengo de Spring, eso me dio formas fáciles de usar hibernate y transacciones. De todos modos, logré que Hibernate funcionara. Ayer, al escribir algo de código para eliminar un grano de DB, tengo esto:¿Por qué obtengo org.hibernate.HibernateException: No CurrentSessionContext configurado

org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions 

El código de eliminación es simplemente:

Session sess = HibernateUtil.getSession(); 
    Transaction tx = sess.beginTransaction(); 
    try { 
     tx.begin(); 
     sess.delete(ims); 
    } catch (Exception e) { 
     tx.rollback(); 
     throw e; 
    } 
    tx.commit(); 
    sess.flush(); 

y mi HibernateUtil.getSession() es:

public static Session getSession() throws HibernateException { 
     Session sess = null; 
     try { 
      sess = sessionFactory.getCurrentSession(); 
     } catch (org.hibernate.HibernateException he) { 
      sess = sessionFactory.openSession(); 
     } 
     return sess; 
    } 

adicional detalles: nunca cierro una sesión de hibernación en mi código, solo al cerrar la aplicación. ¿Esto esta mal? ¿Por qué obtengo esto en eliminar (solo para ese bean, otros sí funcionan) y no en otras operaciones (Insertar, consultar, actualizar)?

leí alrededor y traté de modificar mi método getSession simplemente en un sessionFactory.getCurrentSessionCall(), pero tengo: org.hibernate.HibernateException: No CurrentSessionContext configured!

Hibernat conf:

<hibernate-configuration> 
    <session-factory > 
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
    <property name="hibernate.connection.url">jdbc:mysql://localhost/joptel</property> 
    <property name="hibernate.connection.username">root</property> 
    <property name="hibernate.connection.password">******</property> 
    <property name="hibernate.connection.pool_size">1</property> 
    <property name="show_sql">true</property> 
    <property name="hibernate.hbm2ddl.auto">update</property> 


    ..mappings.. 

    </session-factory> 
</hibernate-configuration> 
+0

¿Cómo se ve el archivo de configuración de hibernación? – Santosh

Respuesta

54

Yo quería preguntarle una cosa, ¿por qué estás tratando de usar el método "OpenSession"?

public static Session getSession() throws HibernateException {   
    Session sess = null;  
    try {   
     sess = sessionFactory.getCurrentSession(); 
    } catch (org.hibernate.HibernateException he) { 
     sess = sessionFactory.openSession();  
    }    
    return sess; 
} 

Usted no tiene que llamar openSession(), porque getCurrentSession() método es siempre devuelve sesión actual (Tratados en el caso de que si lo ha configurado para ser).

lo tengo ... Se tiene que especificar el contexto actual en el archivo de hibernate.cfg.xml

que debe ser:!

<property name="hibernate.current_session_context_class">thread</property> 
10

Sin CurrentSessionContext configurado

Lea la guía de referencia en Contextual Sessions. Está obligado a configure some provided or custom strategy para esto. En una hibernate.cfg.xml, que le configura con

<property name="hibernate.current_session_context_class">...</property> 

Probablemente querrá usar "hilo" como valor para obtener sesiones por-hilo. Al usar Spring, establece automáticamente esto en SpringSessionContext, lo que permite a Spring integrar fácilmente Hibernate con su marco de gestión de transacciones.

Vengo de Spring, que me dio formas fáciles de usar hibernate y transacciones.

Si está familiarizado con Spring, ¿por qué no lo usa para administrar Hibernate aquí? Usted ya debe saber qué tan simple e infalible lo hace.

Nunca cierro una sesión de hibernación en mi código, solo al cerrar la aplicación. ¿Esto esta mal?

Sí, esto está muy mal. Cada sesión no cerrada es una conexión de base de datos abierta, por lo que su aplicación actualmente está sufriendo una hemorragia de conexiones.

intento ilegal de asociar una colección con dos sesiones abiertas

Eso significa exactamente lo que dice. Intentó hacer una operación de persistencia (save(), update(), delete()) en algo que ya estaba asociado a una sesión diferente. Eso es lo que sucederá cuando vaya al azar a abrir nuevas sesiones cada vez, que es lo que está sucediendo desde SessionFactory.getCurrentSession() siempre fallará cuando no se establezca "contexto de sesión actual". En general, nunca abren una sesión solo porque uno no estaba allí. Necesita tener estrategias bien definidas para abrir y cerrar sesiones y nunca dejar que nada abra una sesión fuera de estas "estrategias". Ese es un camino seguro a las filtraciones de recursos y errores como el que ha encontrado.

3

Me enfrenté al mismo problema cuando estoy trabajando en un portal en el que estoy utilizando la primavera remota con Hibernate. Este tipo de problema surge solo si el método de servicio llamado contiene múltiples llamadas DAO que golpean la base de datos con la sesión de hibernación.

Y la solución se establece en la anotación @Transaction para aquellos métodos con múltiples llamadas DAO. (Implica que todas las llamadas de DOA en este método deben realizarse en una transacción).

Cuestiones relacionadas