Luchando para entender el uso apropiado de EntityManager

Estoy comenzando un nuevo proyecto y soy totalmente nuevo en el uso de JPA / Hibernate. Estoy tratando de entender cómo usar EntityManager correctamente. Más precisamente, cuando crear una instancia de ellos, ¿cuántos necesito, debería cerrarlos, debería poner todo en las transacciones?

De todos modos, en mi código actual, recibí una org.hibernate.LazyInitializationException mientras trataba de leer una entidad que guardé previamente. Entendía lo contrario (leer una antigüedad en una transacción y luego tratar de guardar la entidad leída en otra transacción, pero como la transacción ha terminado, la entidad no está administrada, por lo que la operación de salvar falla), pero esto no lo entiendo.

Puse mi código en GitHub ( https://github.com/GaetanLeu/intl ), son solo un par de clases. Mi principal está en src / sandbox / MessageSandbox.java y falla en la línea 28 con la siguiente stacktrace:

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285) at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) at entity.MessageKey_$$_jvstfcc_0.toString(MessageKey_$$_jvstfcc_0.java) at java.lang.String.valueOf(String.java:2854) at java.lang.StringBuilder.append(StringBuilder.java:128) at com.google.common.base.Present.toString(Present.java:88) at java.lang.String.valueOf(String.java:2854) at java.io.PrintStream.println(PrintStream.java:821) at sandbox.MessageSandbox.main(MessageSandbox.java:28) 

También recibí una advertencia de Hibernate diciendo que mi EntityManager ya existe, ¿qué ocurre entonces? ¿El método EntityManagerFactory.createEntityManager devuelve el existente?

 WARN: HHH000436: Entity manager factory name (intl) is already registered. If entity manager will be clustered or passivated, specify a unique value for property 'hibernate.ejb.entitymanager_factory_name' 

Realmente estoy perdido acerca de cuándo crear EntityManagers ^^ Cualquier ayuda sería apreciada, pero por favor explicación simple, soy realmente nuevo en esto.

Oh, por cierto, quiero precisar que no estoy usando Spring, no tengo EJB, quiero manipular EntityManagers manualmente por ahora hasta que lo entiendo. Gracias 🙂

Un entityManager administra un contexto de persistencia , en otras palabras, una instantánea de memoria del estado de la base de datos.

Ver ¿Qué es un objeto de persistencia?

Cada objeto cargado con el entityManager estará en estado administrado (ver ciclo de vida de la entidad) hasta que cierre el EM. Cuando se managed una entidad, se realizará un seguimiento de todos los cambios realizados y luego se mantendrá cuando se vacíe el EM. Si accede a algún atributo de búsqueda diferida, se generará automáticamente una solicitud para cargar dinámicamente los datos, pero si la entidad está en estado separado (si se ha cerrado EM), acceder a un atributo vago dará lugar al error que obtiene.

El scope (/ ciclo de vida) de su EM depende del contexto de su ejecución. Para una aplicación web, por ejemplo, típicamente se creará un EM para cada solicitud http.

Para una aplicación independiente, tiene que importar si la base de datos puede ser actualizada por otra aplicación / hilo o no. Si puede, su contexto persistente puede no ser coherente con el estado de la base de datos y debe crearlo para cada unidad de trabajo (transacción) para evitar eso. De lo contrario, puede crear una única instancia una vez para toda la vida útil de la aplicación y descargarla regularmente.

Para una aplicación CRUD, el ciclo de vida generalmente es el siguiente:

  • crear el EM
  • buscar algunas entidades (están tan administradas, cualquier acceso al atributo perezoso cargará los datos de DB)
  • cerrar el EM (la entidad ahora está separada, cualquier acceso al atributo perezoso llevará a LazyInitializationException)
  • mostrar los datos al usuario

En la validación de actualizaciones del usuario:

  • crear el em
  • abrir una transacción
  • fusionar (adjuntar) sus entidades actualizadas (esto es lo que llama guardar) (si ha configurado algún locking optmistic, em comprobará la versión de la entidad contra la base de datos aquí)
  • eventualmente realizar alguna validación empresarial o actualizaciones adicionales
  • confirmar la transacción y cerrarla (los cambios se eliminarán)

Keep es consciente de que EM es un objeto liviano, barato de crear y destruir, y NO HILO SEGURO.

Por cierto, JPA es una especificación de Java EE que es parte del EJB uno (la parte de persistencia). Su objective es ser utilizado en un contexto contenedor java EE (servidor de aplicaciones Java EE o CDI desde JEE 6). Aún puede usar hibernación en modo independiente a través del contrato de JPA, pero incluso en este caso, se debe considerar el acoplamiento con resorte para aprovechar las características administradas del contenedor.

    Intereting Posts