Relación muchos a uno con @ManyToOne

Relación muchos a uno con @ManyToOneUna de las grandes ventajas que tiene trabajar con JPA, es que te permite hacer relaciones con otras entidades, de esta forma, es posible agregar otras Entidades como atributos de clase y JPA se encargará de realizar el SELECT adicional para cargar esas Entidades.

 

Para comprender esto, analicemos el ejemplo de las facturas, estas siempre son emitidas a un cliente, por lo que el objeto Factura siempre deberá tener una propiedad que represente al cliente. Normalmente, esta propiedad seria el ID, sin embargo, JPA nos permite tener una referencia a la Entidad cliente. Veamos cómo quedaría la Entidad Invoice  (factura)

 

Como podemos apreciar, hemos utiliza la anotación @ManyToOne , la cual nos permite mapear una entidad con otra. Como única regla, es necesario la clase que sea una entidad, es decir, que también esté anotada con @Entity .

 

Por otro lado, tenemos la entidad Customer , la cual se ve de la siguiente manera:

 

Estas dos entidades nos crearán las siguientes tablas:

JPA ManyToOne tables

 

La anotación @ManyToOne cuenta con los siguientes atributos:

  • Optional: indica si la relación es opcional, es decir, si el objeto puede ser null. Esta propiedad se utiliza optimizar las consultas. Si JPA sabe que una relación es opcional, entonces puede realizar un RIGHT JOIN  o realizar la consulta por separado, mientras que, si no es opcional, puede realizar un INNER JOIN  para realizar una solo consulta.
  • Cascade: Esta propiedad le indica que operaciones en cascada puede realizar con la Entidad relacionada, los valores posibles son ALL , PERSIST , MERGE , REMOVE , REFRESH , DETACH y están definidos en la enumeración javax.persistence.CascadeType .
  • Fetch: Esta propiedad se utiliza para determinar cómo debe ser cargada la entidad, los valores están definidos en la enumeración javax.persistence.FetchType  y los valores posibles son:
    • EAGER (ansioso): Indica que la relación debe de ser cargada al momento de cargar la entidad.
    • LAZY (perezoso): Indica que la relación solo se cargará cuando la propiedad sea leída por primera vez.
  • targetEntity: Esta propiedad recibe una clase ( Class ) la cual corresponde a la clase de la relación. No suele ser utilizada, pues JPA puede inferir la clase por el tipo de la propiedad.

 

En nuestro caso, hemos definido la propiedad optional en false, pues toda factura debe de tener forzosamente un Cliente (customer). La propiedad cascade la definimos en ALL  para facilitarnos la explicación de este ejemplo, pero más adelante en este tutorial analizaremos las cascadas en profundidad. La propiedad fetch la definimos en EAGER , aun que para este tipo de relación es su valor por default y no sería necesario definirlo.

 

Ejemplo práctico

Crearemos un pequeño ejemplo que nos permita comprobar cómo trabajar con esta relación, para ello, crearemos una nueva factura con un cliente:

 

Como resultado, podemos observar como han sido insertados la Factura y el Cliente:

JPA Invoices ManyToOne relationship
Tabla de las facturas

 

JPA Customers ManyToOne relationship
Tabla de los clientes

 

Por otra parte, si consultamos la Entidad Invoice, JPA se encargará de cargar al Empleado, vamos el siguiente ejemplo:

 

Como podemos apreciar en la siguiente imagen, no fue necesario ir a consultar el Cliente por separado, si no que JPA se encarga de recuperarlo justo en el momento en que lo necesitamos.

JPA ManyToOne select

 

Finalmente, podemos ver en las siguiente imágenes como es que nos auto genero la tabla de las facturas, en ella podemos apreciar el campo CUSTOMER_ID , el cual es en realidad una llave foránea a la tabla de clientes:

JPA ManyToOne table

 

JPA también nos ayuda a crear los Foreign Keys con la tabla de Clientes:

JPA ManyToOne foreign keys

 

Conclusiones

Hemos podido observar como JPA se encarga de todo lo relacionado a persistir o recuperar el cliente de la base de datos, sin embargo, hay algo que no hemos cubierto, y es la forma en que podemos personalizar la columna, es decir, como podemos indicarle el nombre, si admite nulos o no, etc. Todas esta propiedades las podremos definir en la anotación @JoinColumn  que analizaremos en la siguiente parte del tutorial

AnteriorÍndiceSiguiente

Artículos relacionados

Crear un proyecto JPA En la actualidad existe diversos IDE’s que nos permitirán crear proyecto JPA y en general todos ofrecen las mismas opciones por lo que en realidad sea...
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...
MongoDB Atlas – Database as a Service Hasta hace poco, tener una base de datos 100% funcional y perfectamente administrada, era casi imposible o todo un reto, pues se requiere personal alt...

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 *