En la referencia de hibernación, se afirma varias veces que¿Cómo romper una sesión de Hibernate?
Todas las excepciones lanzadas por Hibernate son fatales. Esto significa que debe retrotraer la transacción de base de datos y cerrar el
Session
actual. No puede continuar trabajando con unSession
que arrojó una excepción.
Una de nuestras aplicaciones heredadas utiliza una sola sesión para actualizar/insertar muchos registros de archivos en una tabla DB. Cada actualización/inserción de registro se realiza en una transacción separada, que luego se confirma (o se retrotrae en caso de que se haya producido un error). Luego, para el siguiente registro, se abre una nueva transacción, y así sucesivamente. Pero la misma sesión se usa durante todo el proceso, incluso si se atrapó HibernateException
en mitad del procesamiento. Estamos utilizando Oracle 9i btw con Hibernate 3.24.sp1 en JBoss 4.2.
Al leer lo anterior en el libro, me di cuenta de que este diseño puede fallar. Así que reformé la aplicación para usar una sesión separada para cada actualización de registro. En una prueba unitaria con una fábrica de simulacros de sesión, puedo verificar que ahora está solicitando una nueva sesión para cada actualización de registro. Hasta aquí todo bien.
Sin embargo, no encontramos forma de reproducir el error de sesión mientras probamos toda la aplicación (¿sería esto una prueba de esfuerzo por cierto, o ...?). Pensamos en cerrar al oyente de la base de datos, pero nos dimos cuenta de que la aplicación mantiene un montón de conexiones abiertas a la base de datos, y el oyente no afectaría esas conexiones. (Esta es una aplicación web, activada una vez por noche por un programador, pero también puede activarse a través del navegador.) Luego intentamos eliminar algunas de esas conexiones en el DB mientras la aplicación estaba procesando las actualizaciones, lo que dio como resultado algunas fallas actualizaciones, pero luego la aplicación felizmente continuó actualizando el resto de los registros. Aparentemente, Hibernate es lo suficientemente inteligente como para reabrir conexiones rotas debajo del capó sin romper toda la sesión.
Por lo tanto, puede que esto no sea un problema crítico, ya que nuestra aplicación parece ser lo suficientemente robusta incluso en su forma original. Sin embargo, el problema sigue molestándome. Me gustaría saber:
- ¿En qué circunstancias la sesión de Hibernate realmente quedar inutilizable después de un
HibernateException
se tiró (Actualización: y cuáles son los síntomas)? - Cómo reproducir esto en una prueba (Actualización: preferiblemente en integración, en lugar de prueba unitaria)?
- (¿Qué es el término apropiado para una prueba de este tipo?)
En cuanto a 1), esto es lo que también entiendo, así que estoy feliz de haber hecho nuestra aplicación más robusta. El problema directo es, ¿cómo verificar esto en una prueba independiente? 2) suena interesante, ya que esto podría hacerse sin modificar la aplicación en sí. –