JPA ofrece 3 estrategias principales para mapear la herencia :
@Inheritance(strategy = SINGLE_TABLE) : Todo se guarda en una sola tabla con una columna discriminadora.
@Inheritance(strategy = JOINED): Se usa una tabla por clase, relacionadas por claves foráneas.
@Inheritance(strategy = TABLE_PER_CLASS): Una tabla para cada clase, sin relaciones.
Veamos un ejemplo usando la estrategia: SINGLE_TABLE.
package com.ejemplo.demo.entidad;
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "tipo_empleado", discriminatorType = DiscriminatorType.STRING)
public abstract class Empleado {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nombre;
// Getters y setters
}
@Inheritance(...): Define la estrategia de herencia.
@DiscriminatorColumn(...): Crea una columna adicional (tipo_empleado) que almacena el tipo real de cada instancia.
📄 Gerente.java
package com.ejemplo.demo.entidad;
import jakarta.persistence.*;
@Entity
@DiscriminatorValue("GERENTE")
public class Gerente extends Empleado {
private String departamento;
// Getters y setters
}
📄 Desarrollador.java
package com.ejemplo.demo.entidad;
import jakarta.persistence.*;
@Entity
@DiscriminatorValue("DESARROLLADOR")
public class Desarrollador extends Empleado {
private String lenguajeFavorito;
// Getters y setters
}
Se crea una única tabla empleado, con las columnas:
id, nombre, departamento, lenguajeFavorito y tipo_empleado (con valores como GERENTE, DESARROLLADOR)
Ventajas de SINGLE_TABLE
• Más simple y rápida para consultas.
• Ideal si la mayoría de los campos son comunes.
Desventajas
• Muchos campos nulos en columnas que sólo usa una subclase.
Otras estrategias:
• JOINED: separa en tablas, y junta usando claves foráneas. Útil si los datos son muy distintos y no querés campos nulos.
• TABLE_PER_CLASS: evita JOINs, y es util cuando no necesitas hacer consultas a nivel de clase padre.
En conclusión SINGLE_TABLE lo usamos cuando tenemos herencia la cual las clases hijas no agregan muchos o ningun dato. JOINED cuando queremos hacer consultas a nivel clase padre y tenemos muchos datos diferentes y TABLE_PER_CLASS cuando no necesitamos hacer query a nivel clase padre.