Aunque se escribieron muchas publicaciones sobre el tema de OpenSession/EntityManagerInViewFilter de Spring, no pude encontrar ninguna que mencionara sus fallas. Por lo que entiendo, y asumiendo una arquitectura típica de aplicaciones web en capas usando una capa de servicio @Transactional, el filtro funciona de la siguiente manera:Por qué no utilizar Spring's OpenEntityManagerInViewFilter
- El filtro intercepta una petición de servlet
- El filtro se abre un EntityManager y se une a el subproceso actual controlador
- web se llama
- controlador web llama a servicio
- transacción interceptor comienza una nueva transacción, recupera la EntityManager hilo de ruedas y se une a la transacción
- servicio se llama, hace algunas cosas con EntityManager, a continuación, vuelve
- interceptor Transacción vacía el EntityManager a continuación, confirma la transacción
- controlador Web prepara vista, a continuación, vuelve
- View está ubicado
- Filtro cierra el EntityManager y lo desvincula del hilo actual
En los pasos 8 y 9, los objetos cargados por el EntityManager del subproceso se siguen administrando. En consecuencia, si las asociaciones diferidas se tocan en estos pasos, se cargarán de la base de datos utilizando el EntityManager aún abierto. Por lo que entiendo, cada acceso requerirá que la base de datos abra una transacción. La administración de transacciones de Spring no lo tendrá en cuenta, de ahí que lo llame "transacción implícita".
veo 2 problemas con esto:
- Cargando varias asociaciones perezosas resultará en múltiples transacciones de bases de datos, un posible golpe en el rendimiento
- El objeto raíz y sus asociaciones perezosas se cargan en diferentes transacciones de bases de datos, por lo que los datos pueden ser obsoletos (por ejemplo, raíz cargada por subproceso 1, asociaciones de raíz actualizadas por subproceso 2, asociaciones de raíz cargadas por subproceso 1)
Por un lado, estos 2 problemas parecen suficientes para rechazar el uso de este filtro (impacto de rendimiento, inconsistencia de datos). Por otro lado, esta solución es muy conveniente, evita escribir varias líneas de código, el problema 1 puede no ser tan notable y el problema 2 puede ser pura paranoia.
¿Qué opinas?
Gracias!