David Gómez Rubio

Analista funcional

Project Manager

Dirección de equipos informáticos

David Gómez Rubio

Analista funcional

Project Manager

Dirección de equipos informáticos

Artículo del Blog

Spring Framework – Diferencia entre la anotación @JoinColumn y el atributo mappedBy

Spring Framework – Diferencia entre la anotación @JoinColumn y el atributo mappedBy

Os mostramos la diferencia entre la anotación @JoinColumn y el atributo mappedBy  y como trabajan en la relación entre tablas y el papel que juega cada uno. 

  • @JoinColumn: Para definir los atributos de una entidad y relacionarlos con la columna de la tabla a la que hacer referencia se utiliza normalmente @Column@JoinColumn se parecen mucho y tiene casi las mismas propiedades, por que podríamos decir que @JoinColumn  es el equivalente de @Column  cuando utilizamos relaciones con Entidades.
  • El atributo mappedBy de las anotaciones @OneToMany, @OneToOne y @ManyToMany define básicamente que la relación va a ser bidireccional, o sea, cada tabla va a tener acceso a la otra de forma directa.

En este artículo rápido, veremos la diferencia entre @JoinColumn y mappedBy en JPA. También mostraremos cómo usarlos en una asociación de uno a muchos @OneToMany.

Partimos teniendo dos entidades: Usuario y Email.

Claramente, un usuario puede tener múltiples direcciones de correo electrónico. Sin embargo, una dirección de correo electrónico dada puede pertenecer exactamente a un solo usuario.

Significa que comparten una asociación de uno a muchos @OneToMany:

JoinColumn MappedBy

Solo con la anotación @ManyToOne en la tabla emails junto con la definición del atributo private Usuario usuario  sería suficiente para que nuestro Framework, a través de JPA  generase de forma automática la Clave Foránea usuarios_id que apuntará a la clave primaria de la tabla usuarios. Pero no es aconsejable que todo el control lo tenga JPA y sus configuraciones por defecto, y siempre se aconseja usar @JoinColumn para especificar sus propiedades y tener nosotros el control.

Propiedades de @JoinColumn :

  • name: Indica el nombre con el que se deberá de crear la columna dentro de la tabla.
  • referencedColumnName: Se utiliza para indicar sobre que columna se realizará el Join de la otra tabla. JPA, por defecto, asume que será el ID de la Entidad a la que apuntamos.
  • unique: Crea una restricción en la tabla para impedir valores duplicados (por defecto es false).
  • nullable: Crea una restricción en la tabla para impedir valores nulos (por defecto es true).
  • insertable: Le indica a JPA si este valor deberá guardarse en la operación de inserción (por defecto es true)
  • updatable: Le indica a JPA si el valor deberá actualizarse durante el proceso de actualización (por defecto es true)
  • columnDefinition: Esta propiedad se utiliza para indicar la instrucción SQL que se deberá utilizar la crear la columna en la base de datos sin depender de la configuración de JPA.
  • table: Le indicamos sobre que tabla deberá realizar el JOIN,  JPA por defecto lo hará a la tabla vinculada a la entidad que apuntamos.
  • foreignKey: Le indica a JPA si debe de crear el Foreign Key con los siguientes posibles valores: CONSTRAINT , NO_CONSTRAINT , PROVIDER_DEFAULT.
@Entity
@Table(name="emails")
public class Email {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String email; 
 
    @ManyToOne(fetch = FetchType.LAZY)
    
	//Sin el @JoinColumn también se crearía la clave foranea pero indicamos
  	//el nombre de la clave foránea e indicamos que no puede ser nula.
  	@JoinColumn(name = "usuarios_id", nullable = false)
    private Usuario usuario;
 
    // ...
 
}

Simplemente significa que nuestra entidad de correo electrónico tendrá una columna de clave externa llamada usuario_id que hace referencia al ID de atributo principal de nuestra entidad de empleado y que la clave foránea no debe de ser nula.

Atributo mappedBy

En resumen mappedBy define el objeto al que pertenece la relación y es obligatorio si la relación es bidireccional.  Por lo que hace que no solo se pueda acceder a la información del usuarios desde el email, sino que también podamos hacerlo en sentido contrario. Exista o no exista la definición expresa del @JoinColumn.

Como habíamos dicho hasta ahora, JPA ya tenía toda la información que necesita para mapear esa relación en nuestra base de datos. Para hacer que esta asociación sea bidireccional, todo lo que hay hacer ahora es añadir el atributo mappedBy del @OneToMany del lado del usuario.

@Entity
@Table(name="usuarios")
public class Usuario {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    //Con esta lista tenemos todos los emails del usuario.
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "usuario")
    private List<Email> emails;
     
    // ...
}

Aquí, el valor de mappedBy es el nombre del atributo de mapeo de asociación en el lado propietario. Con esto, ahora hemos establecido una asociación bidireccional entre nuestros usuarios y entidades de correo electrónico.

Ya hemos visto la diferencia entre la anotación @JoinColumn y el atributo mappedBy. Los 2 describen una relación, los 2 pueden existir por separado o complementados. Siempre dependiendo si la dirección de la relación es unidireccional, bidireccional y si queremos controlar nosotros de forma explicita la creación de las claves foránea.

Índice de contenidos Spring Boot

Taggs:
Escribe un comentario