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:

package com.obb.jpa.jpaturorial.entity.pk;

import java.util.Objects;
import javax.persistence.Id;

/**
 * @author Oscar Blancarte
 */
public class TelephonePK {
    private Long employeId;
    private String telType;

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + Objects.hashCode(this.employeId);
        hash = 59 * hash + Objects.hashCode(this.telType);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final TelephonePK other = (TelephonePK) obj;
        if (!Objects.equals(this.telType, other.telType)) {
            return false;
        }
        if (!Objects.equals(this.employeId, other.employeId)) {
            return false;
        }
        return true;
    }
    /** GET AND SET */
}

Definimos la clase TelephonePK, la cual solamente tiene como atributos el tipo de teléfono y el id del empleado. Observemos que esta no requiere de ningún tipo de anotación, pero si es requerido sobrescribir los métodos hashCode & equals.
La siguiente clase que definimos es la Entidad Telephone la cual representa un teléfono de empleado.

package com.obb.jpa.jpaturorial.entity;

import com.obb.jpa.jpaturorial.entity.pk.TelephonePK;
import java.util.Objects;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;

/**
 * @author Oscar Blancarte
 */
@Entity
@Table(name = "Telephones")
@IdClass(value = TelephonePK.class)
public class Telephone {
    @Id
    private Long employeId;
    @Id
    private String telType;
    
    private String number;

    /** GET, SET, HashCode & Equals */
}

Observemos que esta clase cuanta con el Id del empleado y el tipo de teléfono marcados como @Id, además, tiene la anotación @IdClass a nivel de clase y como valor tiene la clase EmployeePK.
Un dato importante es que tanto la definición de los atributos en la clase ID como en la clase Entidad deben de coincidir a la perfección en caso contrario provocara un error en tiempo de ejecución.

Tras aplicar estos últimos cambios la siguiente tabla será generada:

Tabla con @IdClass

Observemos que la tabla contiene tanto los campos de la entidad Telephone como la clase id TelephonePK.

Tambíen los quiero invitar a ver mi curso de JPA, donde explico todos estos temas aplicados con API REST, https://codmind.com/courses/jpa

👉👉 Los invito a mi Curso de Mastering JPA, donde habla de todos estos temas y crearemos un API REST para probar todos los conceptos de persistencia.
👈👈

En lo particular, esté método para definir llaves primarías compuestas no me agrada mucho, debido a que me obliga a repetir los atributos en las dos clases. En la siguiente sección hablaremos del segundo método para implementar llaves compuestas utilizando la anotación @EmbeddedId.

NOTA: Este artículo es solo una sección del Tutorial de JPA, para ver el contenido completo de este tutorial regresa al Índice en el botón de abajo.

AnteriorÍndiceSiguiente

8 thoughts to “Llaves compuestas con @IdClass”

  1. Como podria realizar lo que es una relacion de tablas de uno a cero-muchos, ya que he leido y JPA no me lo permite como tal, hay alguna manera??

  2. Estimado… gracias por compartir esta información, en este momento de desarrollo me ha sido de mucha utilidad; no tenia idea de que se podía hacer esto en Spring boot. Podrías explicar la diferencia de usar @IdClass o @EmbededId, gracias

    1. Hola Pedro, la diferencia tiene el mismo objetivo, solo que son difernetes formas de mapear los ID de las entidades que tiene Llaves compuestas, con IdClass lo que haces es definir las propiedades como parte de la clase, y con EmbedableId lo que haces es que delegas las propiedades a una clase aparte. En realidad es algo confuso de explicar con detalle por este medio, pero si te interesa, tengo un curso dedicado a JPA, por si quieres darle un vistazo: https://codmind.com/courses/jpa

Deja un comentario

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