Entity Manager & Persistence Context

Tutorial de JPA persistence.xmlHasta el momento solo hemos trabajado con el Entity Manager para realizar las operaciones básicas, pero existen detalles más finos que es necesario entender para convertirnos en expertos de JPA. Cuando trabajamos con JPA es común interactuar con el Entity Manager, ¿pero que tanto sabemos acerca de los Persistence Context en realidad?

 

Primero que nada, tenemos que saber que el Persistence Context se crea mediante un Persistence Unit y el Entity Manager se crea a partir de un Persistence Context, veamos la siguiente imagen para entender mejor:

persistence context

 

Veamos que todo parte del archivo persistence.xml del cual ya hablamos anteriormente, en este archivo se definen los Persistence Unit, y mediante estos es creado el Persistence Context, el Persistence Context tiene la finalidad de delimitar el alcance de las transacciones, pero también está delimitado a administrar las Entidades definidas por el Persistence Unit con el que fue creado.  Adicionalmente, el Entity Manager hace referencia a un Persistence Context el cual será utilizado para administrar las entidades y las transacciones.

 

Una de las ventajas de tener varios Persistence Unit, es que nos permite definir diferentes configuraciones para cada uno, de esta manera podemos delimitar las entidades de cada módulo e incluso una configuración de base de datos diferentes para cada uno.

 

Container-Managed Entity Manager

 

Básicamente existen dos formas de trabajar con JPA, la más simple es cuando lo utilizamos en aplicaciones SE o de escritorio y la segunda forma que es la que estudiaremos en esta sección, es cuando lo utilizamos en ambientes de Java EE con EJB.

La principal característica de utilizar Entity Manager administrado por el contenedor, es que es el mismo Container el que se encarga de abrir y cerrar las transacciones, por lo que el programador solo se preocupa por implementar la lógica de negocio despreocupándose en la totalidad de las transacciones.

En ambientes Java EE se suele utilizar la anotación@PersistenceContext  para crear el EntityManager, como veremos en el siguiente EJB.

 

 

Cuando utilizamos la anotación@PersistenceContext  el contenedor inyecta de forma automática una referencia válida del EntityManager creado a partir de la Persistence Unit JPA_PU, de esta forma, el programador podrá utilizar el EntityManager en cualquier método que defina, y las transacciones será administradas de forma automática.

 

Ahora bien, existen dos variantes de los Container-Managed, Transaction-Scope y Extended, los cuales son utilizados en circunstancias diferentes. Para utilizar una variante o la otra, es necesario definirlo en la anotación@PersistenceContext  mediante la propiedad type. Los valores posibles sonTRANSACTION  yEXTENDED  como veremos a continuación:

 

 

En caso de no definir la propiedad type, el valor por default será TRANSACTION, lo cual está bien, porque es por lejos la variante más utilizada.

 

Transaction-Scope

 

La variante Transaction-Scope es la variante utiliza por default, por lo que no es necesario definir la propiedad type para utilizarla. Esta variante tiene la particularidad de que el contexto de persistencia solo será válido durante le ejecución de la operación de negocio, una vez que la operación termine el contexto de persistencia se destruye y todas las entidades relacionadas con el Entity Manager será descartadas.

Este tipo de estrategias se utiliza para EJB sin estado como los@Stateless, pues cada invocación a una operación de negocio se espera que realice una acción, persista y retorne un resultado, y cada ejecución tendrá un contexto de persistencia diferente, garantizando de esta forma que el servicio siempre arroje el mismo resultado para la misma entrada.

Veamos un ejemplo de un servicio de creación de empleados:

 

 

Imaginemos el siguiente escenario, tenemos una aplicación que carga el empleado en pantalla utilizando el métodogetEmployeeById, esta consulta al empleado mediante el ID y lo retorna, la aplicación utiliza el empleado consultado para mostrarlo en pantalla, luego, modificamos el nombre del empleado y guardamos los cambios mediante el métodoupdateEmployeeName.

Lo primero que hace la aplicación es consultar el empleado, hasta aquí todo bien, pero cuando actualizamos el nombre del empleado, vemos que realizamos un find mediante el ID del empleado, podríamos pensar que como ya lo hemos consultado anteriormente mediante el métodogetEmployeeById este solo lo retomará del cache sin realizar una nueva consulta a la base de datos, sin embargo, Transaction-Scope garantiza que cada ejecución crea un nuevo PersistenceContext en blanco, por lo que el empleado que anteriormente ya habíamos consultado será nuevamente consultado, debido que en la segunda llamada al métodoupdateemployeeName el Persistence Context está en blanco.

 

No te preocupes por las anotaciones@TransactionAttribute, más adelante las explicaremos por ahora pasémoslas por alto.

 

Extended

 

La segunda variante es Extended, que como su nombre nos lo indica, se trata de un Contexto de Persistencia Extendido, donde el contexto persistirá durante todo el tiempo de vida de la sesión, sin importar el número de operaciones o transacciones que se realicen.

A diferencia de Transaction-Scope, en esta variante todos los cambios realizados en el Persistence Context seguirán vigentes, por lo que cada ejecución que realicemos se favorecerá de las ejecuciones pasadas.

Este tipo de variante es utilizada cuando trabajamos con EJB con sesión como el@Stateful, veamos el mismo ejemplo anterior pero esta vez utilizando un EJB con sesión y la variante Extended.

 

 

En este caso las cosas son un poco diferentes. Primero que nada, se realiza la consulta del empleado mediante el métodogetEmployeeById y el empleado es retornado, cuando la ejecución del método termina, el Persistence Context continúa existiendo, por lo que cuando se realiza la actualización del nombre del empleado y se realiza la consulta del empleado, el Entity Manager ya no consulta al empleado, pues este ya fue consultado en el método anterior. Finalmente, el nombre es actualizado y al terminar el método se hace un commit de la transacción. Al finalizar el método el Contexto de persistencia continua activo hasta que la sesión finaliza.

 

 

Application-Managed Entity Manager

 

La segunda forma de trabajar con JPA es delegar al programador la responsabilidad de administrar las transacciones, este escenario se da con mucha más frecuencia en aplicaciones de escritorio, aunque existen escenarios donde es utilizado en entornos de Java EE.

Básicamente el programador tiene que crear el EntityManager a través del EntityManagerFactory y tiene que abrir y cerrar las transacciones cada vez que requiera.

Veamos cómo quedaría el escenario anteriormente planteado utilizando application-managed:

Podemos apreciar que el constructor de la clase estamos creando manualmente el EntityManager en lugar de simplemente inyectarlo como el Container-Managed, la otra diferencia es en el métodoupdateEmployeeName, ya que para poder persistir los cabios tenemos que abrir y cerrar la transacción con los métodos beign y commit.

 

AnteriorÍndiceSiguiente

Artículos relacionados

Definición de columnas con @Column Una de las principales características cuando trabajamos con base de datos es que todas las tablas tienen Columnas, y dichas columnas esta mapeadas co...
Estrategias de carga con @Basic @Basic es una anotación que nos permite controlar el momento en que una propiedad es cargada desde la base de datos, evitando que traer valores que no...
Definir llave primaría con @Id Al igual que en las tablas, las entidades también requieren un identificador( ), dicho identificador deberá de diferenciar a la entidad del resto. Com...

Oscar Blancarte

Ideológico, Innovador y emprendedor, Padre, Tecnólogo y Autor, amante de la ciencia y la tecnología en todos sus colores y sabores. Arquitecto de software & Full Stack Developer con experiencia en la industria del desarrollo de software y la consultoría. Amante de la programación y el Ajedrez.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *