Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

Mapear una jerarquía de herencia de entidades

En esta guía, aprenderá a mapear una jerarquía de clases Java a una colección de MongoDB mediante la extensión Hibernate ORM. Cuando una subclase Java extiende una clase padre y hereda sus campos, las clases forman una jerarquía. Hibernate ORM proporciona estrategias de herencia que determinan cómo la extensión almacena cada clase en la jerarquía. La estrategia que elija determinará qué colecciones contienen sus datos y la estructura de los documentos resultantes.

La extensión Hibernate ORM admite las siguientes estrategias de herencia:

  • Herencia de tabla única: la extensión Hibernate ORM almacena toda la jerarquía de clases en una sola colección.

  • Superclases mapeadas: Una superclase que no es una entidad aporta sus campos a cada subclase sin tener una colección propia.

La extensión no admite las estrategias de herencia JOINED y TABLE_PER_CLASS. Para obtener más información, consulte la sección Estrategias no compatibles de esta guía.

En la estrategia de herencia de tabla única, el framework almacena cada clase en una jerarquía dentro de la misma colección de MongoDB. Para usar esta estrategia, aplique la anotación @Inheritance(strategy = InheritanceType.SINGLE_TABLE) a la entidad raíz, la clase padre de nivel más alto en la jerarquía.

Dado que la colección contiene documentos que se corresponden con varias clases, la extensión debe registrar la clase a la que pertenece cada documento. La extensión almacena esta información en un campo discriminador al guardar un objeto. Al consultar la colección, la extensión lee el valor del discriminador para determinar qué clase instanciar.

Para especificar el campo discriminador, aplique la anotación @DiscriminatorColumn a la entidad raíz. Para establecer el valor discriminador de una clase, aplique la anotación @DiscriminatorValue a la clase.

El siguiente ejemplo asigna una jerarquía Movie a la colección movies. Las subclases Actor y Director heredan el campo name de Movie, pero cada subclase también añade su propio campo. Cada documento almacena "actor" o "director" en el campo discriminador role.

@Entity
@Table(name = "movies")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "role")
public abstract class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String name;
// Getter and setter methods
}
@Entity
@DiscriminatorValue("actor")
public class Actor extends Movie {
private List<String> awards;
// Getter and setter methods
}
@Entity
@DiscriminatorValue("director")
public class Director extends Movie {
private String studio;
// Getter and setter methods
}

Cuando se llama al método persist() en una instancia Actor o una instancia Director, la extensión inserta el documento correspondiente en la colección movies. Cada documento contiene los campos que define su propia clase y el valor discriminador para esa clase:

{ "_id": ObjectId("..."), "role": "actor", "name": "Andrew Garfield", "awards": ["Golden Globe Award"] }
{ "_id": ObjectId("..."), "role": "director", "name": "Greta Gerwig", "studio": "Warner Bros." }

El ejemplo anterior utiliza un discriminador de cadena, el tipo de discriminador predeterminado. Para cambiar este tipo, establezca el elemento discriminatorType de la anotación @DiscriminatorColumn. Establezca este elemento en DiscriminatorType.CHAR para almacenar el discriminador como un carácter, o en DiscriminatorType.INTEGER para almacenarlo como un número entero.

Importante

Los discriminadores de caracteres y enteros requieren un valor explícito.

Hibernate no asigna por defecto el nombre de la clase al valor del discriminador de una clase, ya sea para discriminadores de caracteres o enteros. Si asigna discriminatorType a DiscriminatorType.CHAR o DiscriminatorType.INTEGER, debe agregar una anotación @DiscriminatorValue a la entidad raíz y a cada subclase, incluso si nunca instancia directamente la entidad raíz.

La colección movies contiene documentos para cada clase en la jerarquía Movie. Al consultar una de estas clases, la extensión Hibernate ORM filtra por el campo discriminador para que la consulta devuelva únicamente documentos para esa clase. Este filtro depende de la clase que se consulte:

  • Si se consulta una subclase, la extensión coincide con los documentos cuyo discriminador es igual al valor del discriminador de esa subclase. En el ejemplo anterior, la consulta Actor solo coincide con los documentos en los que role es "actor".

  • Si se consulta la clase raíz, la extensión no añade ningún filtro. La consulta lee todos los documentos de la colección y utiliza el valor discriminador de cada uno para devolver un objeto de la clase correcta. Al consultar Movie en el ejemplo anterior, se devuelven los documentos Actor y Director. Si la colección contiene un documento cuyo valor discriminador no se corresponde con ninguna clase de la jerarquía, la consulta devuelve HibernateException.

Para obtener más información sobre cómo consultar entidades, consulte la guía Especificar una consulta.

Una superclase mapeada comparte asignaciones de campos con sus subclases sin convertirse en una entidad propia. Para crear una superclase mapeada, aplique la anotación @MappedSuperclass a la superclase. Dado que una superclase mapeada no es una entidad, la extensión Hibernate ORM no crea una colección para ella y no se puede consultar directamente.

Cada subclase que extiende una superclase mapeada se asigna a su propia colección. En cada documento, la extensión almacena los campos heredados y los campos propios de la subclase como campos de nivel superior. La extensión no anida los campos heredados ni los almacena por separado.

El siguiente ejemplo define una superclase mapeada MovieDetails que proporciona los mapeos de identificador y nombre para una entidad Genre y una entidad Language:

@MappedSuperclass
public abstract class MovieDetails {
@Id
@ObjectIdGenerator
private ObjectId id;
private String name;
// Getter and setter methods
}
@Entity
@Table(name = "genres")
public class Genre extends MovieDetails {
private String description;
// Getter and setter methods
}
@Entity
@Table(name = "languages")
public class Language extends MovieDetails {
private String code;
// Getter and setter methods
}

En el ejemplo anterior, la anotación @MappedSuperclass permite que MovieDetails defina las asignaciones id y name sin convertirse en una entidad. Las anotaciones @Entity y @Table en Genre y Language asignan entonces cada subclase a su propia colección.

Como resultado, la extensión no crea una colección para MovieDetails. En su lugar, la extensión almacena los documentos Genre en la colección genres y los documentos Language en la colección languages. Cada documento contiene los campos _id y name que MovieDetails asigna, además de los campos que define su clase correspondiente:

{ "_id": ObjectId("..."), "description": "Serious, narrative-driven stories.", "name": "Drama" }
{ "_id": ObjectId("..."), "code": "en", "name": "English" }

La extensión Hibernate ORM no admite las siguientes estrategias de herencia de Hibernate ORM, que almacenan una única jerarquía de clases en varias tablas:

  • InheritanceType.JOINEDAlmacena cada clase en su propia tabla y une las tablas para reconstruir una instancia.

  • InheritanceType.TABLE_PER_CLASSAlmacena cada clase concreta en su propia tabla y combina las tablas para consultar la jerarquía.

Si asigna sus clases con cualquiera de las estrategias anteriores, la extensión arroja un FeatureNotSupportedException.

Importante

Se producen errores al iniciar.

La extensión Hibernate ORM valida la estrategia de herencia al crear la instancia SessionFactory. Una aplicación que utilice una estrategia no compatible no podrá iniciarse.

Para obtener más información sobre cómo crear entidades y asignar datos incrustados, consulte la guía Crear entidades para representar colecciones.

Para aprender a usar sus entidades para ejecutar operaciones de base de datos, consulte las guías "Realizar operaciones CRUD" y "Especificar una consulta".

Para ver una lista de las características que admite la extensión Hibernate ORM, consulte la página de compatibilidad de características.

Para obtener más información sobre las estrategias de herencia de Hibernate ORM, consulte la sección "Herencia" en la documentación de Hibernate ORM.