Trabajar con objetos pesados @Lob

Tutorial de JPA @LobJPA nos permite mediante la anotaci贸n @Lob mapear con la base de datos objetos pesados, como podr铆a ser im谩genes, xml, binarios, cadenas de texto extensas, json, etc. Cualquier objeto que pueda tener un tama帽a muy grande o de longitud indefinida.

 

@Lob

 

La anotaci贸n @Lob es lo 煤nico que se requiere para indicarle a JPA que ese campo es un objeto pesado y que debe de tratarse como tal. Por lo general se utiliza con los arreglos de bytes, ya que permite almacenar cualquier cosa.

La anotaci贸n @Lob no tiene ning煤n atributo, por lo que solo ser谩 necesario definirla para que funcione. Otro punto importante es que esta anotaci贸n crear谩 una columna de tipo longblob en mysql y podr铆a variar seg煤n el manejador de base de datos utilizados, pero al final siempre ser谩 un campo para objetos pesados.

Para poner en pr谩ctica esta anotaci贸n, retomaremos la entidad Employee, en esta ya hab铆amos agregado la propiedad photo聽 de tipo byte[], en la cual vamos a almacenar la foto del empleado, sin embargo, no hab铆amos entrado en detalles. La entidad Employee se ve de la siguiente manera:

(m谩s…)

Estrategias de carga con @Basic

Tutorial de JPA @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 son necesario al momento de cargar el objeto. Esta anotaci贸n es utilizada generalmente para anotar objetos pesados, como una imagen o un archivo binario.

 

@Basic

 

En JPA existe dos conceptos que son claves para entender c贸mo es que JPA carga los objetos desde la base de datos y estos son claves para mejorar el rendimiento de la aplicaci贸n, estos conceptos se explican a continuaci贸n:

  • Lazy loading (Carga demorada): Los objetos de carga demorada no ser谩n cargados desde la base de datos cuando el objeto sea creado, pero ser谩 cargado en cuanto se acceda a la propiedad. De esta manera JPA identifica cuando la propiedad es accedida por primera vez para cargar el valor desde la base de datos.
    • @Basic( fetch = FetchType.LAZY )
  • Eager loading (Carga ansiosa o temprana): Este es la utilizada por default para la mayoria de las propiedades en JPA, a excepci贸n de las colecciones las cuales las analizaremos mas adelante.
    • @Basic( fetch = FetchType.EAGER )

(m谩s…)

Mapeo de fechas con @Temporal

Tutorial de JPA @Temporal

Mediante la anotaci贸n @Temporal es posible mapear las fechas con la base de datos de una forma simple. Una de las principales complicaciones cuando trabajamos con fecha y hora es determinar el formato empleado por el manejador de base de datos. Sin embargo, esto ya no ser谩 m谩s problema con @Temporal.

Mediante el uso de @Temporal es posible determinar si nuestro atributo almacena Hora, Fecha u Hora y fecha, y es posible utilizar la clase Date o Calendar para estos fines. Yo siempre recomiendo utilizar Calendar, pues tiene muchas m谩s operaciones para manipular fecha y hora.

Se pueden establecer tres posibles valores para la anotaci贸n:

  • DATE: Acotara el campo solo a la Fecha, descartando la hora.
    • @Temporal(TemporalType.DATE)
  • TIME: Acotara el campo solo a la Hora, descartando a la fecha.
    • @Temporal(TemporalType.TIME)
  • TIMESTAMP: Toma la fecha y hora.
    • @Temporal(TemporalType.TIMESTAMP)

(m谩s…)

JPA y los m茅todos hashCode & equals

Tutorial de JPA persistence.xmlPor defecto, todos los objetos en Java heredan de la case Object los m茅todos hashCode y equals los cuales sirvan para identificar si dos variables hacen referencia al mismo objeto.
El comportamiento de facto del m茅todo hashCode retorna la posici贸n en memoria de un objeto, y el m茅todo equals compara el hashCode de los dos objetos evaluados, de esta forma, si las dos variables hacen referencia a la misma posici贸n de memoria, entonces se dice que son igual, de lo contrario son diferentes.
En el caso de las Entidades, la implementaci贸n default de estos m茅todos no funciona correctamente, debido a que una Entidad de dice que es igual a otra si se cumplen dos condiciones:

鈥 Los dos objetos son de la misma clase.
鈥 El valor de su ID (@Id) son iguales

Si estas dos condiciones se cumplen entonces las dos entidades son iguales sin importar que no hagan referencia a mismo objeto en memoria. Debido a esto, es que es importante sobrescribir estos dos m茅todos para que eval煤en a una Entidad por las dos condiciones mencionadas.

Implementando los m茅todos hashCode & equals

Algo que me ha llamado mucho la atenci贸n es que a pesar de que estos dos m茅todos son b谩sicos y que se utilizan con regularidad, muchas personas no entienden como trabajan internamente y a煤n menos como sobrescribirlos correctamente, si eres una de esas personas, no te preocupes ya que los IDE鈥檚 ya tiene por default utilidades que nos ayudan a generarlos de forma adecuada.
Lo primero que haremos ser谩 abrir la entidad Employee que hemos venido trabajando a lo largo de este tutorial. Luego presionaremos Source > Insert Code del men煤 principal, esto arrojara una peque帽a lista de acciones, seleccionamos la opci贸n equals() and hashCode(). Nos arrojara una pantalla como la siguiente:
M茅todo equals y hashcode (m谩s…)

Mapeo de enumeraciones con @Enumerated

Tutorial de JPA @EnumeratedUna de las ventajas de utilizar enumeraciones en Java, es podemos limitar los valores posibles para una propiedad, forzando a los desarrolladores a utilizar los valores ya definidos y evitando el margen de error.

@Enumerated

Con JPA tambi茅n es posible utilizar enumeraciones y pueden ser de mucha ayuda para asegurar que los programadores persistan un valor v谩lido dentro de una lista previamente definida. JPA nos permite mediante la anotaci贸n @Enumerated definir la forma en que una enumeraci贸n ser谩 persistida, las cuales se explican a continuaci贸n:

  • String: permite persistir la enumeraci贸n por su nombre, lo que significa que ser谩 una columna alfanum茅rica. La anotaci贸n quedar铆a as铆:
    • @Enumerated(value = EnumType.STRING)
  • Ordinal: esta estrategia persiste un valor entero que corresponde al valor ordinal o posici贸n de valor en la enumeraci贸n. La anotaci贸n quedar铆a de la siguiente manera:
    • @Enumerated(value = EnumType.ORDINAL)

Retomaremos la entidad Employee que hemos venido analizando en todo este tutorial y le agregaremos una nueva propiedad que corresponda al status:

(m谩s…)

Definici贸n de columnas con @Column

Tutorial de JPAUna de las principales caracter铆sticas cuando trabajamos con base de datos es que todas las tablas tienen Columnas, y dichas columnas esta mapeadas contra los atributos de las entidades, para lo cual es necesario que JPA identifique que columna mapea contra cada atributo de la clase y es aqu铆 donde entra @Column.

 

 

@Column

La anotaci贸n @Column nos permitir谩 definir aspectos muy importantes sobre las columnas de la base de datos de la base de datos como lo es el nombre, la longitud, constrains, etc. En caso de no definir esta anotaci贸n en los atributos, JPA determinara el nombre de la columna de forma autom谩tica mediante el nombre del atributo, por lo que siempre es recomendable establecer esta anotaci贸n en todos los atributos de la clase y evitarnos problemas. (m谩s…)

Llaves compuestas con @IdClass

Tutorial de JPA @IdClassExisten ocasiones en donde se requieres marcar m谩s de un campo como @Id, conformando con esto una llave primar铆a compuesta. En estos casos se requiere complementar la entidad con una clase adicional que ser谩 utilizada como ID y adem谩s tendr谩 que ser referenciada desde la clase donde se requiere una llave compuesta.

La utilizaci贸n de @IdClass es una de las dos opciones para definir llaves primarias compuestas, y esta consiste en crear una clase adicional 煤nicamente con los campos que corresponden a la llave primaria.
Veamos un caso concreto, normalmente un empleado puede tener m谩s de un tel茅fono, entonces, podr铆amos crear una tabla donde la llave primaria sea el ID del empleado y el tipo de tel茅fono, de esta forma nos aseguramos de tener solo un tipo de tel茅fono por empleado. Veamos c贸mo quedar铆a la clase ID: (m谩s…)

Definir llave primar铆a con @Id

Tutorial de JPA @IdAl igual que en las tablas, las entidades tambi茅n requieren un identificador( @Id聽), dicho identificador deber谩 de diferenciar a la entidad del resto. Como regla general, todas las entidades deber谩n definir in ID, de lo contrario provocaremos que el EntityManager marque error a la hora de instanciarlo.

El ID es importante porque ser谩 utilizando por EntityManager a la hora de persistir un objeto, y es por este que puede determinar sobre que registro hacer el select, update o delete. JPA soporta ID simples de un solo campo o ID complejos, formados por m谩s de un campo, sin embargo, esta secci贸n abordaremos 煤nicamente los ID simples y abordaremos las llaves compuestas en la siguiente secci贸n del tutorial.

(m谩s…)