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 cerrarlos? Alguna sugerencia por favor.
Respuestas:
Supongo que la respuesta es: depende .
Su administrador de 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 esperanza de vida de su contexto.
Consideremos que creará un administrador de entidad por solicitud del usuario. Por lo tanto, mientras atiende una solicitud determinada, mantendrá abierto el administrador de su entidad y, cuando termine con él, lo cerrará.
En una aplicación JSE, es posible que haya considerado que le gustaría mantener abierto el administrador de su entidad durante toda la vida útil de la aplicación (suponiendo que no esté tratando con grandes cantidades de datos) y luego lo cierra cuando se cierra la aplicación.
En pocas palabras, cuándo lo abres y cuándo 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 como está creando el EM en el método, debe cerrarlo antes de regresar; de lo contrario, ya no tendrá acceso a él nuevamente (a menos que lo mantenga en algún registro, que no es evidente en el código).
Si no lo cierra, sus entidades se mantendrán como 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 JPA contiene más detalles. En la sección 7.7 Contextos de persistencia administrados por aplicaciones , dice:
Entonces, como puede ver, el administrador de entidades es la interfaz pública a través de la cual 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 las aplicaciones Java EE, puede tener un contexto de persistencia con alcance de transacción o un contexto de persistencia extendida . En la aplicación JSE, el desarrollador controla la naturaleza del contexto .
Cuando le solicita una entidad a su administrador de entidades, busca la entidad en su contexto adjunto, si encuentra la entidad allí, 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.
Con alcance de transacción
En una aplicación Java EE que usa el contexto de persistencia de alcance de transacción, cuando accede por primera vez a su administrador de entidad, verifica si la transacción JTA actual tiene un contexto adjunto si aún no hay contexto presente, se crea un nuevo contexto y el administrador de entidad está vinculado a este contexto. Luego, la entidad se lee de la base de datos (o del caché si está presente) y se coloca en el contexto. Cuando su transacción finaliza (confirmar o deshacer), el contexto deja de ser válido y las entidades que contiene se separan. Este es el escenario clásico para los 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 beans, ya que no le gusta comprometerse hasta que el bean se haya marcado para su eliminación, ¿verdad? En esos casos, debe utilizar un contexto de persistencia extendido. En este caso, el contexto de persistencia se crea cuando se necesita por primera vez, pero no dejará de ser válido hasta que marque el bean con estado 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 con estado, 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 los elimine manualmente.
Administrado por aplicación
Siempre puede crear una instancia manual de la fábrica de su administrador de entidad y su administrador de entidad. Esto es lo que normalmente haría en una aplicación JSE, ¿verdad?
Para este tipo de aplicaciones, normalmente no tiene un contenedor para manejar las transacciones JTA, ¿verdad? Por lo tanto, utiliza transacciones locales de recursos y es responsable de confirmar o revertir manualmente los cambios.
Para este tipo de aplicación, cuando crea una instancia de su administrador de entidad, se le adjunta automáticamente un contexto.
Dependiendo de su aplicación, puede decidir crear un administrador de entidad global cuyo ciclo de vida esté vinculado a la vida de la aplicación en sí. Es un administrador de entidad única durante toda la vida útil de la aplicación. En estos casos, su contexto se creará y destruirá con su administrador de entidad.
O bien, puede crear un administrador de entidad por conversación (es decir, transacción) con el usuario de su aplicación. El alcance, en este caso, lo determina usted, pero aún así, su contexto será creado y destruido con su administrador de entidad.
fuente
EntityManager
debe ser insignificante. Desde mi punto de vista, EntityManager es solo una abstracción para tratar la unidad de trabajo de la transacción actual. Creo que está perfectamente bien crear y destruir uno por transacción. Ahora, tiene otras implicaciones, porque losEntityManager
servidores como un caché transaccional para sus entidades y, por lo tanto, tener un alcance de transacción bien definido y tratar adecuadamente con las entidades podría aprovechar este caché.