5 Estrategias de herencia¶
Introducción¶
Java Persistence API (JPA) proporciona varias estrategias para mapear la herencia en un modelo de objetos a una estructura de base de datos relacional. Estas estrategias permiten definir cómo se representan las jerarquías de clases en la base de datos. A continuación, se describen las estrategias de herencia comunes en JPA con ejemplos y esquemas:
Supongamos que tenemos una jerarquía de clases de productos con una clase base Product
y dos subclases Book
y Electronics
. Cada una de las estrategias a continuación se ilustrará utilizando esta jerarquía.
Herencia de tabla única (Single Table Inheritance)¶
En esta estrategia, se utiliza una sola tabla para almacenar todas las entidades de la jerarquía. Se agrega una columna discriminadora (generalmente una columna de tipo) para indicar la clase concreta de cada fila.
Una columna discriminadora es una columna en una tabla de base de datos que se utilizar para identificar la clase concreta de una entidad en una jerarquía de herencia. Por ejemplo, en una tabla producto, en la columna product_type se indica el tipo de producto que es, y ese tipo está relacionado con una subclase de la clase Product.
Un valor discriminado es el valor que se le dará en esa columna discriminadora en caso de ser del tipo específico.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
version="2.2">
<entity class="com.example.model.Product">
<table name="Product"/>
<inheritance strategy="SINGLE_TABLE"/>
<attributes>
<id name="id">
<generated-value strategy="IDENTITY"/>
</id>
<basic name="name"/>
<!-- Otros campos y mapeos específicos de Product -->
</attributes>
<discriminator-column name="product_type" length="1"/>
</entity>
<entity class="com.example.model.Book">
<table name="Product"/>
<attributes>
<discriminator-value>B</discriminator-value>
<basic name="author"/>
<!-- Otros campos y mapeos específicos de Book -->
</attributes>
</entity>
<entity class="com.example.model.Electronics">
<table name="Product"/>
<attributes>
<discriminator-value>E</discriminator-value>
<basic name="manufacturer"/>
<!-- Otros campos y mapeos específicos de Electronics -->
</attributes>
</entity>
</entity-mappings>
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "product_type")
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
// Otros campos y métodos
}
@Entity
@DiscriminatorValue("B")
public class Book extends Product {
private String author;
// Otros campos y métodos específicos de Book
}
@Entity
@DiscriminatorValue("E")
public class Electronics extends Product {
private String manufacturer;
// Otros campos y métodos específicos de Electronics
}
Herencia de tabla por clase (Table per Class Inheritance)¶
En esta estrategia, cada clase concreta en la jerarquía de herencia tiene su propia tabla en la base de datos. Se crea una tabla separada para cada clase, y todas las tablas comparten una clave principal.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
version="2.2">
<entity class="com.example.model.Product">
<table name="Product"/>
<inheritance strategy="TABLE_PER_CLASS"/>
<attributes>
<id name="id">
<generated-value strategy="IDENTITY"/>
</id>
<basic name="name"/>
<!-- Otros campos y mapeos específicos de Product -->
</attributes>
</entity>
<entity class="com.example.model.Book">
<attributes>
<basic name="author"/>
<!-- Otros campos y mapeos específicos de Book -->
</attributes>
</entity>
<entity class="com.example.model.Electronics">
<attributes>
<basic name="manufacturer"/>
<!-- Otros campos y mapeos específicos de Electronics -->
</attributes>
</entity>
</entity-mappings>
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
// Otros campos y métodos
}
@Entity
public class Book extends Product {
private String author;
// Otros campos y métodos específicos de Book
}
@Entity
public class Electronics extends Product {
private String manufacturer;
// Otros campos y métodos específicos de Electronics
}
Herencia de tabla por subclase (Table per Subclass Inheritance)¶
En esta estrategia, se crea una tabla para la clase base y una tabla separada para cada subclase. Las tablas de las subclases tienen una relación uno a uno con la tabla de la clase base utilizando una clave foránea.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
version="2.2">
<entity class="com.example.model.Product">
<table name="Product"/>
<inheritance strategy="JOINED"/>
<attributes>
<id name="id">
<generated-value strategy="IDENTITY"/>
</id>
<basic name="name"/>
<!-- Otros campos y mapeos específicos de Product -->
</attributes>
</entity>
<entity class="com.example.model.Book">
<attributes>
<basic name="author"/>
<!-- Otros campos y mapeos específicos de Book -->
</attributes>
</entity>
<entity class="com.example.model.Electronics">
<attributes>
<basic name="manufacturer"/>
<!-- Otros campos y mapeos específicos de Electronics -->
</attributes>
</entity>
</entity-mappings>
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
// Otros campos y métodos
}
@Entity
public class Book extends Product {
private String author;
// Otros campos y métodos específicos de Book
}
@Entity
public class Electronics extends Product {
private String manufacturer;
// Otros campos y métodos específicos de Electronics
}
Estas son tres de las estrategias de herencia más comunes en JPA. La elección de la estrategia de herencia depende de tus necesidades específicas y del diseño de tu base de datos. Cada estrategia tiene sus ventajas y desventajas, por lo que debes seleccionar la que mejor se adapte a tu aplicación y modelo de datos.