2012-02-20 63 views
7

Tengo una plataforma basada en Hibernate, construida a partir de servlets sin estado (una se utiliza para registrar un usuario y el resto para consultar el db).Gestión de sesiones con Java Hibernate

estoy usando sesiones de Hibernate de la siguiente manera:

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
if ((null == session) || (session.isOpen() == false)) { 
    session = HibernateUtil.getSessionFactory().openSession(); 
} 

Actualmente no cierro la sesión al final del servlet con el fin de evitar openSession() llamada (tratando de utilizar las sesiones abiertas si es posible).

¿Cuál es la mejor práctica? ¿Cuándo se supone que debo cerrar estas sesiones?

¿Puedes dar un ejemplo?

¡Gracias de antemano!

Respuesta

13

La mejor práctica es, en la mayoría de los casos, la sesión por solicitud. Es decir, abra una sesión al principio de manejar una solicitud y ciérrela al final. Puede hacerlo en un Servlet Filter, por ejemplo.

Tener una sesión para toda la aplicación es malo, porque acumulará una gran cantidad de entidades en su caché de primer nivel, que es una pérdida de memoria. También puede producir resultados indeterminados cuando varios clientes lo usan al mismo tiempo.

Su código, sin embargo, no usa una sesión para toda la aplicación; utiliza el concepto de "sesión actual", que abre una sesión y la almacena en un contexto (un ThreadLocal por ejemplo). Pero si no lo cierras, permanecerá allí para siempre. Además, causará los mismos problemas que se describieron anteriormente, porque los subprocesos se reutilizan en una aplicación web, y una nueva solicitud obtendrá una sesión anterior no cerrada en algún momento.

+0

Estoy de acuerdo que una sesión para toda la aplicación es una mala idea, pero ¿qué hay de conseguir sesión actual para cada solicitud en lugar de cierre de la sesión abierta, especialmente cuando se están aplicando la primavera e hibernan juntos? – Shilan

3

Siempre es mejor abrir una nueva sesión para cada solicitud, y cerrar la sesión una vez que se procesa la solicitud. Al igual que

Session session = HibernateUtil.getSessionFactory().openSession(); 

en lugar de

Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 

Si utilizamos el método getCurrentSession(), tansaction.commit()/rollback() cierra la conexión.

+0

"nueva sesión para cada solicitud" es anti-patrón – zond

0

Lo mejor es administrar una sesión de hibernación es abrir una nueva sesión para cada solicitud. Todo depende de cómo se obtenga la sesión.

  • si utiliza SessionFactory.getCurrentSession(), podrás obtener una "sesión actual" que está ligado al ciclo de vida de la transacción y se vacía automáticamente y se cierra cuando la transacción extremos (o cometen retrotracción)
  • si decide utilizar sessionFactory.openSession(), tendrá que administrar la sesión por su cuenta y vaciarla y cerrarla "manualmente".
if (!session.isOpen()) { 
     session = session.getSessionFactory().openSession(); 
     session.beginTransaction(); 
} 
0

mejor que te recomiendo usar marco de primavera.Causa en primavera puede usar @Transactional en el nivel de método y la sesión se creará y cerrará automáticamente por el administrador de transacciones (a menos que esté usando cualquier sesión abierta en el interceptor de vista) usando AOP que es manejado internamente por framework.

@Autowired 
EntityManager em; 

@Transactinal 
void save(User user){ 
    em.persist(user); 
} 

eso all.spring es divertido: D

Cuestiones relacionadas