¿Debería estar cerrado JPA Entity Manager?

Tengo el método a continuación.

public Profile readUser(String email){ EntityManager em = EMF.get().createEntityManager(); return em.find(Profile.class, email); } 

¿Está bien el uso anterior del administrador de entidades? O es necesario cerrar em? Cualquier sugerencia, por favor.

Supongo que la respuesta es: depende .

El administrador de su entidad es la clave para obtener acceso al contexto donde residen las entidades. Si su aplicación es una aplicación JSE, debe considerar cuál es la expectativa de vida de su contexto.

Consideremos que creará un administrador de entidades por solicitud del usuario. Por lo tanto, mientras asista a una solicitud determinada, mantendrá abierto el administrador de su entidad y cuando termine con ella, la cerrará.

En una aplicación JSE, puede haber considerado que le gustaría mantener el administrador de su entidad abierto durante toda la vida de la aplicación (suponiendo que no esté tratando con grandes cantidades de datos) y luego cerrarla cuando la aplicación se apaga.

En pocas palabras, cuando lo abres y cuando cierras depende completamente de tu estrategia y tu diseño. Lo cierra cuando ya no necesita las entidades en su contexto.

En su ejemplo, eso no es evidente, pero dado que está creando EM en el método, debe cerrarlo antes de volver, de lo contrario ya no tendrá acceso a él (a menos que lo mantenga en algún registro, que es no es evidente en el código).

Si no lo cierra, sus entidades se mantendrán adjuntas, incluso después de que haya terminado de usarlas. Su contexto se mantendrá vivo incluso cuando ya no pueda acceder a su EM.

La especificación de JPA contiene más detalles. En la sección 7.7 Contextos de persistencia gestionados por la aplicación dice:

Cuando se usa un administrador de entidad administrado por aplicación, la aplicación interactúa directamente con la fábrica del administrador de entidades del proveedor de persistencia para administrar el ciclo de vida del administrador de entidades y para obtener y destruir contextos de persistencia.

Todos los contextos de persistencia administrados por la aplicación tienen un scope extendido y pueden abarcar varias transacciones.

El método EntityManagerFactory.createEntityManager y los EntityManager close e isOpen se utilizan para administrar el ciclo de vida de un administrador de entidades gestionado por aplicaciones y su contexto de persistencia asociado.

El contexto de persistencia extendida existe desde el punto en el que se ha creado el gestor de entidades utilizando EntityManagerFactory.createEntityManager hasta que el gestor de entidades se cierra mediante EntityManager.close .

Un contexto de persistencia extendido obtenido del administrador de la entidad administrada por la aplicación es un contexto de persistencia independiente que no se propaga con la transacción.

[…] El método EntityManager.close cierra un administrador de entidades para liberar su contexto de persistencia y otros recursos. Después de realizar una llamada de cierre, la aplicación no debe invocar ningún otro método en la instancia de EntityManager excepto getTransaction e isOpen , o se IllegalStateException la IllegalStateException . Si se invoca el método de cierre cuando una transacción está activa, el contexto de persistencia permanece administrado hasta que se completa la transacción.

El método EntityManager.isOpen indica si el administrador de entidades está abierto. El método isOpen devuelve verdadero hasta que se haya cerrado el administrador de entidades. Para comprender realmente cómo funciona esto, es vital comprender la relación entre el administrador de la entidad y el contexto.

Entonces, como puede ver, el administrador de entidades es la interfaz pública a través de la cual usted accede a sus entidades, sin embargo, sus entidades residen en un contexto, adjunto a su administrador de entidades. Comprender el ciclo de vida de los diferentes tipos de contextos responderá a su pregunta.

Los contextos de persistencia pueden ser de diferentes tipos. En aplicaciones Java EE, puede tener un contexto de persistencia con ámbito de transacción o un contexto de persistencia extendida . En la aplicación JSE, el desarrollador controla la naturaleza del contexto.

Cuando solicita una entidad a su administrador de entidad, busca a la entidad en su contexto adjunto, si encuentra la entidad allí, luego la devuelve; de ​​lo contrario, recupera la entidad de la base de datos. Las llamadas posteriores para esta entidad en contexto devolverán la misma entidad.

Aspecto de transacción

En una aplicación Java EE que utiliza el contexto de persistencia con ámbito de transacción, cuando accede por primera vez a su administrador de entidades, comprueba si la transacción JTA actual tiene un contexto adjunto, si aún no hay contexto, se crea un nuevo contexto y el administrador de entidades es vinculado a este contexto. Luego, la entidad se lee desde la base de datos (o desde la memoria caché, si está presente) y se coloca en el contexto. Cuando la transacción finaliza (confirmación o reversión), el contexto deja de ser válido y las entidades que aparecen se separan. Este es el escenario clásico para beans de sesiones sin estado.

 @PersistenceContext(unitName="EmplService") EntityManager em; 

Esto también significa que dependiendo de cómo diseñe sus transacciones, puede terminar con más de un contexto.

Contexto de persistencia extendida

En una aplicación Java EE con beans de sesión con estado, es posible que desee que el contexto sobreviva a múltiples invocaciones de bean, ya que no desea comprometerse hasta que el bean haya sido marcado para su eliminación, ¿verdad? En esos casos, necesita usar un contexto de persistencia extendido. En este caso, el contexto de persistencia se crea cuando se necesita por primera vez, pero no se volverá inválido hasta que marque el bean statefull para su eliminación.

 @PersistenceContext(unitName="EmplService", type=PersistenceContextType.EXTENDED) 

Esto significa que, independientemente de la instancia del administrador de entidades que se inyecte en este bean en llamadas posteriores de los métodos de beans de sesión statefull, puede estar seguro de que siempre accederá al mismo contexto y, por lo tanto, incluso las llamadas posteriores devolverán el mismo ejemplo, porque es el mismo contexto.

Además, sus cambios no se eliminarán hasta que el bean esté marcado para su eliminación o usted los enjuague manualmente.

Gestionado por la aplicación

Siempre puede instanciar manualmente la fábrica de su administrador de entidades y su administrador de entidades. Esto es lo que normalmente harías en una aplicación JSE, ¿verdad?

Para este tipo de aplicaciones, normalmente no tiene un contenedor para gestionar las transacciones de JTA, ¿verdad? Por lo tanto, utiliza las transacciones locales de recursos y usted es responsable de realizar o deshacer cambios manualmente.

Para este tipo de aplicación, cuando crea una instancia de su administrador de entidades, se le agrega automáticamente un contexto.

Dependiendo de su aplicación, puede decidir crear un administrador de entidades global cuyo ciclo de vida se adjunta a la vida de la aplicación. Es decir, un único administrador de entidades durante toda la vida de la aplicación. En estos casos, su contexto será creado y destruido con su administrador de entidades.

O bien, podría crear un administrador de entidades por conversación (es decir, transacción) con su usuario de la aplicación. El scope en este caso lo determina usted, pero aún así, su contexto será creado y destruido con su administrador de entidades.