Y qué tipo de estrategias alternativas usas para evitar LazyLoadExceptions?

Entiendo que una sesión abierta en la vista tiene problemas con:

  • Capas de las aplicaciones que se ejecutan en diferentes jvm
  • Las transacciones se confirman sólo al final, y más probablemente a usted le gustan los resultados antes.

Pero, si sabes que tu aplicación se ejecuta en una sola máquina virtual, ¿por qué no aliviar el dolor mediante el uso de una sesión abierta en la vista de estrategia?

  • Es OSIV se considera una mala práctica? ¿Por quién?
  • Y – lo que son buenas alternativas?
  • Esta paz de texto si de costura de los desarrolladores: Hay varios problemas con esta aplicación, la más grave que nunca podemos estar seguros de que una transacción es exitosa hasta que nos comprometemos itbut por el tiempo de la «sesión abierta en la vista de» transacción se confirma, la vista es totalmente rendida, y la representación de la respuesta puede que ya han salido para el cliente. ¿Cómo podemos notificar al usuario de que su transacción fue exitosa?
  • y aquí está el enlace: redhat.com/docs/manuals/jboss/jboss-eap-4.2/doc/seam/…
  • Esta entrada del blog para los pros y los contras y mi propia experiencia al respecto – blog.jhades.org/open-session-in-view-pattern-pros-and-cons
  • Veo un problema, pero no estoy seguro OSIV causando el problema, en mi aplicación me estoy haciendo la Inicialización Perezosa de error cuando se utilizan varios Nodo servidor con un equilibrador de carga. El mismo código funciona correctamente con un servidor, pero el tiempo que agregar uno más en el servidor con el que empezar a dar la Inicialización Perezosa de error al azar

InformationsquelleAutor HeDinges | 2009-07-09

9 Comentarios

  1. 44

    Porque el envío posiblemente no inicializado Proxies, especialmente de las colecciones, en la capa de la vista y la activación de hibernación de carga desde allí, puede ser preocupante, tanto desde el rendimiento y la comprensión del punto de vista.

    Comprensión:

    Utilizando OSIV ‘contamina’ la capa de la vista con las preocupaciones relacionadas con la capa de acceso a datos.

    La capa de la vista no es preparar para manejar un HibernateException que puede suceder cuando la carga perezosa, pero es de suponer que la capa de acceso a datos.

    El rendimiento:

    OSIV tiende a tirar entidad apropiada de la carga debajo de la alfombra – que tienden a no darse cuenta de que sus colecciones o de las entidades de la perezosamente inicializado ( tal vez N+1 ). Más comodidad, menos control.


    Actualización: ver El OpenSessionInView antipattern para una discusión más amplia sobre este tema. El autor enumera tres puntos importantes:

    1. cada inicialización perezosa obtendrá una consulta lo que significa que cada entidad tendrá N + 1 consultas, donde N es el número de perezoso asociaciones. Si la pantalla se presenta la tabla de datos, la lectura de Hibernación del registro es un gran indicio de que ustedes no hagan lo que usted debe
    2. esta completamente derrotas arquitectura de capas, ya que sully tus uñas con base de datos en la capa de presentación. Este es un marco conceptual, con, para que yo pudiera vivir con él, pero no hay un corolario
    3. por último, pero no menos importante, si se produce una excepción, mientras que la captura de la sesión, que tendrá lugar durante la escritura de la página: no se puede presentar una limpia página de error para el usuario y la única cosa que puedes hacer es escribir un mensaje de error en el cuerpo
    • Ok, es ‘contamina’ la capa de la vista con hibernate excepción. Pero, en cuanto a rendimiento, yo creo que el problema es bastante similar a acceder a un servicio de la capa que le devolverá su dto. Si usted se enfrentan a un problema de rendimiento, entonces usted debe optimizar ese problema específico con un inteligente o a una consulta más ligero dto. Si usted tiene que desarrollar también de servicio de muchos métodos para manejar las posibilidades de que usted podría necesitar en la vista, que también están «contaminando» la capa de servicio. no?
    • Una diferencia es que retrasa el cierre de la sesión de Hibernate. Se espera para el JSP, para ser procesado/escrito/etc, y que mantiene los objetos en la memoria por más tiempo. Que puede ser un problema, especialmente si usted necesita para escribir datos en la sesión de cometer.
    • No tiene sentido decir que OSIV perjudica el Rendimiento. Qué alternativas existen, excepto para el uso de DTOs? En ese caso, siempre tienen un bajo rendimiento debido a que los datos utilizados por cualquier vista tendrá que ser cargado incluso para las vistas que no lo necesita.
    • Creo que la contaminación funciona al revés. Si necesito con ganas de carga de los datos, la capa de lógica (o peor la capa de acceso a datos) necesita saber la forma en que un objeto se van a mostrar. Cambiar la vista y que terminan cargando cosas que no necesitan o falta de objetos que usted necesita. Una de Hibernación Excepción es un error y así como el envenenamiento como cualquier otra excepción inesperada. Pero el rendimiento es un problema. El rendimiento y la escalabilidad cuestiones obligan a poner más el pensamiento y la obra en su capa de acceso a datos, y posiblemente de la fuerza de la sesión se cerró antes
    • la vista y te terminan cargando cosas que no necesitan o falta de objetos que usted necesita». Esta es exactamente la misma. Si cambia la vista, es mucho mejor para cargar cosas que no necesita (como que son más propensos a estar con ganas de ir a buscarlos) o encontrar objetos perdidos que tendría la carga Diferida excepción, de dejar que la carga de la vista de ella perezosamente como que resultará en la N+1 problema, y ni siquiera saben lo que está sucediendo. Así que la OMI su mejor la capa de servicio (y usted) sabe lo que es enviado fuera de la vista de la carga de perezosamente y usted no sabe nada acerca de ella.
    • Hay algunos realmente buenos argumentos en contra de que OSIV anti-patrón de enlace; alguien lee este debe leer a través de ellos.

  2. 36

    Para una descripción más detallada, puedes leer mi Sesión Abierta En La Vista Anti-Patrón artículo. De otra manera, aquí está un resumen de por qué no deberías usar una Sesión Abierta En la Vista.

    Sesión abierta En la Vista requiere un mal enfoque a la obtención de datos. En lugar de dejar el negocio de la capa de decidir lo que mejor para recuperar todas las asociaciones que son necesarios por la capa de la Vista, se obliga a que el Contexto de Persistencia para permanecer abierto para que la capa de la Vista puede activar el Proxy de inicialización.

    ¿Por qué es Hibernate Sesión Abierta en la Vista se considera una mala práctica?

    • La OpenSessionInViewFilter llama a la openSession método de la subyacente SessionFactory y obtiene una nueva Session.
    • La Session está enlazado a la TransactionSynchronizationManager.
    • La OpenSessionInViewFilter llama a la doFilter de la javax.servlet.FilterChain objeto de referencia y la petición se procesa
    • La DispatcherServlet se llama, y las rutas de la solicitud HTTP a la subyacente PostController.
    • La PostController llama a la PostService para obtener una lista de Post entidades.
    • La PostService abre una nueva transacción, y la HibernateTransactionManager se reutiliza la misma Session que fue inaugurado por el OpenSessionInViewFilter.
    • La PostDAO recopila la lista de Post entidades sin inicializar cualquier asociación perezosa.
    • La PostService confirma la transacción subyacente, pero la Session no es cerrado, ya que se abrió externamente.
    • La DispatcherServlet se inicia en la representación de la interfaz de usuario, la cual, a su vez, se desplaza el perezoso asociaciones y provoca su inicialización.
    • La OpenSessionInViewFilter puede cerrar el Session, y la base de datos de la conexión se libera así.

    A primera vista, esto podría parecer que no es una cosa terrible, pero, una vez que los ven desde una perspectiva de la base de datos, una serie de defectos comienzan a hacerse más evidentes.

    La capa de servicio se abre y se cierra una transacción de base de datos, pero después de esto, no hay ninguna transacción explícita pasando. Por esta razón, todos los adicionales comunicado emitido desde la interfaz de usuario de representación fase se ejecuta en el modo auto-commit. Auto-commit pone presión en el servidor de base de datos, ya que cada instrucción debe vaciar el registro de transacciones en el disco, por lo tanto, causando una gran cantidad de tráfico de e/S en la base de datos secundarios. Una optimización sería para marcar el Connection como de sólo lectura que permitirá que el servidor de base de datos para evitar la escritura en el registro de transacciones.

    No hay separación de las preocupaciones más debido a que las declaraciones son generados tanto por la capa de servicio y por la interfaz de usuario proceso de representación. Escribir las pruebas de integración que afirmar que el número de declaraciones en las que se genera, requiere ir a través de todas las capas (web, servicio, DAO), mientras que tener la aplicación desplegada en un contenedor web. Incluso cuando se utiliza una base de datos en memoria (por ejemplo, HSQLDB) y un ligero servidor web (por ejemplo, Jetty), estas pruebas de integración va a ser más lento para ejecutar que si las capas se separan y el back-end de las pruebas de integración se utiliza la base de datos, mientras que el front-end de las pruebas de integración se burlaban de la capa de servicio completo.

    La capa de interfaz de usuario se limita a navegar asociaciones que pueden, a su vez, activan N+1 consulta de problemas. Aunque Hibernate ofrece @BatchSize de la obtención de las asociaciones en lotes, y FetchMode.SUBSELECCIÓN para hacer frente a este escenario, las anotaciones están afectando el valor predeterminado plan de recuperación, por lo que se aplican a todos los negocios de casos de uso. Por esta razón, una capa de acceso a datos de la consulta es mucho más conveniente, ya que puede ser adaptado para el presente caso de uso captura de datos requisitos.

    Por último, pero no menos importante, la conexión de base de datos puede realizarse en todo el procesamiento de interfaz de usuario de fase(dependiendo de su conexión de modo de lanzamiento), que aumenta de conexión tiempo de concesión y de los límites de la general, el rendimiento de las transacciones debido a la congestión en la conexión de base de datos a la piscina. Más que la conexión se lleva a cabo, la más otras solicitudes simultáneas que se va a esperar a tener una conexión de la piscina.

    Así que, o bien obtener la conexión a cabo durante demasiado tiempo, se debe adquirir la/liberación de conexiones múltiples para una sola petición HTTP, por lo tanto, poniendo presión en la conexión subyacente de la piscina y limitar la escalabilidad.

    Primavera De Arranque

    Por desgracia, Sesión abierta a la Vista está habilitado por defecto en la Primavera de Arranque.

    Así, asegúrese de que en el application.properties archivo de configuración, usted tiene la entrada siguiente:

    spring.jpa.open-in-view=false

    Esto deshabilitará OSIV, de modo que usted puede manejar el LazyInitializationException de la manera correcta.

    • El uso de una Sesión Abierta en la Vista con auto-commit es posible, pero no de la manera que se esperaba, por la Hibernación de los desarrolladores. Así que, a pesar de Sesión Abierta en la Vista tiene sus inconvenientes, auto-commit no es porque usted puede simplemente apagarlo y todavía lo utilizan.
    • Usted está hablando acerca de lo que sucede dentro de una transacción, y eso es cierto. Pero la Capa de Web fase de representación que sucede fuera de Hibernación, por lo tanto, usted consigue el modo de confirmación automática. Tiene sentido?
    • Creo que es una variante que no es la óptima para una Sesión Abierta en la Vista. La sesión y la transacción debe permanecer abierta hasta que la vista ha sido prestados, entonces no hay ninguna necesidad de que el modo de confirmación automática.
    • La sesión permanece abierta. Pero la transacción no. Abarca la transacción a través de todo el proceso no es óptimo, ya que aumenta su longitud y bloqueos se mantienen durante más tiempo que el necesario. Imagínese lo que sucede si la vista arroja una RuntimeException. Se la reversión de transacciones debido a que el procesamiento de interfaz de usuario fallado?
    • Muchas gracias por muy detallada respuesta! Yo sólo cambiar la guía en la final desde la primavera de inicio de los usuarios probablemente no usar jpa de esa manera.
    • Que son muy bienvenidos. Si la Primavera de Inicio de los usuarios no utilizar OSIB, esta respuesta de StackOverflow no habría más de 100 upvotes.

  3. 24
    • las transacciones pueden ser cometidos en la capa de servicio – transacciones no relacionadas con OSIV. Es el Session que permanece abierta, no una transacción de ejecución.

    • si su nivel de capa de aplicación se extienden a través de múltiples máquinas, entonces usted bastante no puede uso OSIV – tiene que inicializar todo lo que usted necesita antes de enviar el objeto sobre el cable.

    • OSIV es un agradable y transparente (es decir, ninguno de su código es consciente de que se le ocurre) manera de hacer uso de los beneficios en el rendimiento de carga diferida

    • En cuanto al primer punto, esto es, al menos no lo es para el original OSIV de la JBoss wiki, también se encarga de la transacción de la demarcación en torno a la solicitud.
    • Que parte te hizo pensar así?
  4. 13

    No diría que la Sesión Abierta En Vista de que se considera una mala práctica; lo que le da esa impresión?

    Abre la Sesión-En-View es un enfoque simple para el manejo de sesiones con Hibernate. Porque es simple, a veces simplista. Si usted necesita un control de grano fino sobre sus transacciones, tales como tener múltiples transacciones en una solicitud, Abrir la Sesión En el punto de Vista no es siempre un buen enfoque.

    Como otros han señalado, hay algunas concesiones a OSIV — eres mucho más propenso a la N+1 problema, ya que es menos probable que darse cuenta de lo que las transacciones que estás lanzando. Al mismo tiempo, significa que usted no necesita cambiar su capa de servicio para adaptarse a los cambios de menor importancia en su punto de vista.

  5. 5

    Si estás usando una Inversión de Control (IoC) como el recipiente de la Primavera, puede que desee leer sobre bean alcance. Esencialmente, te estoy diciendo la Primavera para darme una Hibernación Session objeto cuyo ciclo de vida se extiende por toda la solicitud (es decir, que se ha creado y destruido en el inicio y el final de la petición HTTP). Yo no tiene que preocuparse acerca de LazyLoadExceptions ni de cerrar la sesión desde el contenedor de IoC las arregla para mí.

    Como se ha mencionado, usted tendrá que pensar acerca de N+1 SELECCIONAR los problemas de rendimiento. Usted siempre puede configurar su Hibernación de la entidad después de hacer deseosos de unirse a la carga en lugares donde el desempeño es un problema.

    El grano de alcance de la solución no es una fuente específica. Sé PicoContainer ofrece la misma capacidad y estoy seguro de que otras maduro contenedores IoC ofrecer algo similar.

    • ¿Tienes un puntero a una implementación real de Hibernación sesiones están disponibles en la vista a través de solicitud ámbito de los granos?
  6. 4

    En mi propia experiencia, OSIV no es tan malo.
    El único arreglo que hice es el uso de dos diferentes transacciones:
    – la primera, inaugurada en la «capa de servicio», donde tengo la «lógica de negocio»
    – la segunda se abrió justo antes de la representación de vista

  7. 3

    Acabo de hacer un post sobre algunas pautas sobre cuándo utilizar una sesión abierta en la vista en mi blog. Échale un vistazo si usted está interesado.

    http://heapdump.wordpress.com/2010/04/04/should-i-use-open-session-in-view/

    • Como por LO general la regla de oro, si usted está proporcionando una respuesta, es mejor que hacer más que solo link en otra parte. Tal vez proporcione una o dos frases o elementos de la lista dando a la esencia. Está bien el enlace, pero desea proporcionar un poco más de valor. De lo contrario, podría desea simplemente para comentar y poner el enlace.
    • el enlace en la respuesta a esto es que vale la pena leer, proporciona una buena orientación sobre cuándo utilizar OSIV y no
  8. 1

    Estoy v. oxidado en Hibernación.. pero creo que es posible tener varias transacciones en una sesión de Hibernate. Así que tu los límites de la transacción no tiene que ser la misma sesión de inicio/parada de eventos.

    OSIV, la omi, principalmente es útil porque podemos evitar escribir código para el inicio de un ‘contexto de persistencia» (un.k.una. período de sesiones) cada vez que la solicitud tiene que hacer una DB de access.

    En su capa de servicio, usted probablemente tendrá que hacer las llamadas a los métodos que han de transacción diferentes necesidades, tales como » Necesaria, Nuevo, etc.’ La única cosa que estos métodos necesitan es que alguien (yo.e el OSIV filtro) ha puesto en marcha el contexto de persistencia, de modo que la única cosa que tiene que preocuparse es de – «hey dame la sesión de hibernate para este hilo.. necesito hacer algunas DB cosas».

  9. 1

    Esto no ayuda demasiado, pero usted puede comprobar mi tema aquí:
    * Hibernate Cache1 OutOfMemory con OpenSessionInView

    Tengo algunas OutOfMemory problemas debido a OpenSessionInView y una gran cantidad de entidades cargado, porque se quedan en modo de Hibernación de la caché de nivel 1 y no la basura recolectada (me carga un montón de entidades con 500 elementos por página, pero todas las entidades permanecer en la caché)

Dejar respuesta

Please enter your comment!
Please enter your name here