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

Crear entidades para representar colecciones

En esta guía, puedes aprender cómo crear entidades de Hibernate ORM que representen colecciones de MongoDB. Las entidades son clases de Java que definen la estructura de tus datos. Cuando se utiliza la extensión Hibernate ORM, se puede asociar cada entidad a una colección de MongoDB y usar estas entidades para interactuar con los documentos de la colección.

Tip

Tutorial de entidades

Para ver un tutorial que muestra cómo modelar relaciones uno-a-muchos utilizando entidades y la extensión Hibernate ORM, consulta la Modelado de relaciones con Hibernate ORM y MongoDB entrada de blog de Foojay.

MongoDB organiza y almacena documentos en una representación binaria llamada BSON que permite un procesamiento de datos flexible. Esta sección describe el soporte de la extensión Hibernate ORM para campos BSON, que puede incluir en sus entidades.

Tip

Para obtener más información sobre cómo MongoDB almacena los datos BSON, consulta BSON Types en el manual de MongoDB Server.

La siguiente tabla describe los tipos de campos BSON admitidos y sus equivalentes de la extensión Hibernate ORM que se pueden usar en las entidades de Hibernate ORM:

Tipo de campo BSON
Tipo de campo de extensión
Descripción de BSON

null

null

Representa un valor nulo o la ausencia de datos.

Binary

byte[]

Almacena datos binarios con subtipo 0.

String

char, java.lang.Character, java.lang.String, char[], java.time.ZoneId, java.time.ZoneOffset o java.util.TimeZone

Almacena valores de cadena codificados en UTF-8. Los tipos ZoneId y TimeZone almacenan su ID, como Europe/Paris. El tipo ZoneOffset almacena su ID de desplazamiento, como +02:00.

Int32

int, java.lang.Integer, o java.time.Year

Almacena enteros de 32bits con signo.

Int64

long or java.lang.Long

Almacena enteros de 64bits con signo.

Double

double or java.lang.Double

Almacena valores de punto flotante.

Boolean

boolean or java.lang.Boolean

Almacena valores de true o false.

Decimal128

java.math.BigDecimal or java.time.Duration

Almacena valores decimales de 28 bits. Los valores de java.time.Duration almacenan la duración en nanosegundos.

ObjectId

org.bson.types.ObjectId

Almacena identificadores únicos de 12bytes que MongoDB utiliza como claves primarias.

Date

java.time.Instant

Almacena fechas y horas en milisegundos desde la época Unix.

Object

@org.hibernate.annotations.Struct embebible agregado

Almacena documentos incrustados con valores de campo asignados según sus tipos respectivos. @Struct incrustables agregados también podrían contener atributos de arreglo o Collection.

Array

Array, java.util.Collection (o subtipo) de tipos admitidos

Almacena valores de arreglo con elementos mapeados según sus tipos respectivos. Los arreglos de caracteres requieren la configuración de la propiedad de configuración hibernate.type.wrapper_array_handling.

Nota

La anotación @JdbcTypeCode no es compatible.

La extensión Hibernate ORM no admite la anotación @org.hibernate.annotations.JdbcTypeCode y genera una excepción si se utiliza esta anotación para anular la asignación de tipos de un campo.

Hibernate ORM serializa cualquier tipo Java que implemente java.io.Serializable a datos binarios cuando no tiene otra asignación para ese tipo. Para evitar que sus datos se almacenen en este formato, la extensión Hibernate ORM rechaza los siguientes tipos y lanza una excepción al iniciar la aplicación. Esta comprobación se aplica a claves primarias, campos ordinarios, atributos incrustables y elementos de colección.

La siguiente tabla describe los tipos de campos no compatibles y sus alternativas compatibles:

Categoría
Tipos no compatibles
Alternativa respaldada

Fecha y Hora

java.util.Calendar, java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.time.LocalTime, java.time.LocalDateTime, java.time.ZonedDateTime, java.time.OffsetTime, java.time.OffsetDateTime

Utilice java.time.Instant.

BSON Values

org.bson.types.BSONTimestamp, org.bson.types.Binary, org.bson.types.Code, org.bson.types.CodeWithScope, org.bson.types.CodeWScope, org.bson.types.MinKey, org.bson.types.MaxKey, org.bson.types.Symbol, org.bson.types.Decimal128

Utilice byte[] para datos binarios y java.math.BigDecimal para valores decimales. Los demás tipos no tienen equivalente.

Documentos BSON

org.bson.Document, org.bson.BsonDocument, org.bson.RawBsonDocument, org.bson.BsonDocumentWrapper

Utilice un elemento incrustable agregado @org.hibernate.annotations.Struct.

Para crear una entidad que represente una colección de MongoDB, crea un nuevo archivo Java en el directorio base del paquete de tu proyecto y agrega la clase de tu entidad a dicho archivo. En la clase de tu entidad, especifica los campos que deseas almacenar y el nombre de la colección.

El elemento name de la anotación @jakarta.persistence.Table representa el nombre de tu colección de MongoDB. También puedes configurar el elemento opcional schema para que aparezca como prefijo del nombre de la colección, como se describe en la sección Calificadores de esquema de esta guía. Utiliza la siguiente sintaxis para definir una entidad:

@Entity
@Table(name = "<collection name>")
public class <EntityName> {
@Id
// Specify your primary key field here
private <field type> <field name>;
// Include additional fields here
private <field type> <field name>;
// Parameterized constructor
public <EntityName>(<parameters>) {
// Initialize fields here
}
// Default constructor
public <EntityName>() {
}
// Getter and setter methods
public <field type> get<FieldName>() {
return <field name>;
}
public void set<FieldName>(<field type> <field name>) {
this.<field name> = <field name>;
}
}

Para utilizar tus entidades, puedes consultarlas en tus archivos de aplicación. Para obtener más información sobre las operaciones CRUD en la extensión Hibernate ORM, consulta la guía Realizar operaciones CRUD.

Importante

El nombre del campo de clave primaria debe ser _id

MongoDB requiere que el campo de clave primaria se asigne al campo _id. Puede establecer explícitamente el nombre de la columna del campo @Id mediante la anotación @Column o la anulación orm.xml. Si establece este nombre con un valor distinto de _id, la extensión Hibernate ORM generará un error FeatureNotSupportedException durante el arranque. Para solucionar este error, elimine la anotación @Column o establezca su nombre en _id.

Esta validación no se aplica a las asignaciones XML de Hibernate Mapping (HBM) heredadas. Si asigna su entidad mediante HBM XML, la extensión Hibernate ORM cambia silenciosamente el nombre de la columna de identificador a _id en lugar de generar una excepción.

La anotación @Table acepta un elemento opcional schema que se antepone al nombre de la colección. Al configurar ambos elementos, la extensión Hibernate ORM asigna la entidad a una colección llamada <schema name>.<collection name>.

Un calificador de esquema solo cambia el nombre de la colección. Un esquema no es una base de datos MongoDB independiente. Cada colección con un calificador de esquema reside en la base de datos a la que se conecta su instancia SessionFactory. Dado que estas colecciones comparten una base de datos, una transacción puede abarcar varios esquemas.

Utilice la siguiente sintaxis para aplicar un calificador de esquema:

@Entity
@Table(schema = "<schema name>", name = "<collection name>")
public class <EntityName> {
// Define your fields, constructors, and methods here
}

Nota

Limitaciones del calificador de esquema

La extensión Hibernate ORM rechaza el elemento catalog de la anotación @Table y la propiedad de configuración hibernate.default_catalog durante el arranque. Si su aplicación necesita acceder a varias bases de datos MongoDB, cree una instancia SessionFactory independiente para cada base de datos.

La extensión Hibernate ORM rechaza el uso de un punto (.) en el nombre de una tabla o un esquema durante el arranque. Esta restricción se aplica a los nombres de tablas primarias, secundarias, de unión y de colección, así como a los nombres de esquema establecidos mediante el atributo schema o la propiedad de configuración hibernate.default_schema.

Esta clase de entidad de muestra Movie.java define una entidad Movie que incluye la siguiente información:

  • @Entity anotación que marca la clase como una entidad ORM de Hibernate

  • @Table anotación que asigna la entidad a la colección movies de los Conjuntos de datos de muestra de Atlas

  • @Id y @ObjectIdGenerator anotaciones que designan el campo id como la llave primaria y configuran la generación automática de ObjectId

    Tip

    Valores de llave primaria

    Este ejemplo especifica el campo ObjectId como clave principal de la entidad, pero también puede establecer los campos String o int como clave principal mediante la anotación @Id. Para obtener más información, consulte Tipos de campos no compatibles.

  • Campos privados que representan datos de películas

  • Constructores por defecto y parametrizados para la instanciación de entidades

  • Métodos getter y setter que proporcionan acceso a los campos de la entidad

package org.example;
import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private List<String> cast;
private List<String> directors;
public Movie(String title, String plot, int year, List<String> cast, List<String> directors) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
this.directors = directors;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public List<String> getCast() {
return cast;
}
public void setCast(List<String> cast) {
this.cast = cast;
}
public List<String> getDirectors() {
return directors;
}
public void setDirectors(List<String> directors) {
this.directors = directors;
}
}

Tip

Para aprender más sobre los campos utilizados en la definición de la clase de entidad, consulta la sección Campos BSON de MongoDB de esta guía.

La extensión Hibernate ORM puede asignar automáticamente identificadores numéricos consecutivos a sus entidades. Es posible que falten algunos números si se revierte una transacción o si una aplicación no utiliza todos los identificadores que reservó.

La extensión Hibernate ORM admite identificadores generados por secuencia para los tipos short, int y long, y para los tipos encapsulados Short, Integer y Long.

Puedes usar las anotaciones @GeneratedValue y @SequenceGenerator para agregar identificadores generados por secuencia a tu entidad. El siguiente ejemplo reserva identificadores en bloques de 50 del contador movies_SEQ:

@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "movies_SEQ"
)
@SequenceGenerator(
name = "movies_SEQ",
sequenceName = "movies_SEQ",
allocationSize = 50
)
private Long id;

Las anotaciones controlan cómo la extensión Hibernate ORM crea el ID:

  • @GeneratedValue Le indica a la extensión Hibernate ORM que cree el valor del campo id. Sus atributos strategy y generator definen cómo la extensión crea el ID:

    • strategy: AUTO o SEQUENCE. Con AUTO, la extensión Hibernate ORM utiliza una secuencia y no es necesario declarar un @SequenceGenerator. Con SEQUENCE, la extensión Hibernate ORM utiliza el generador de secuencias denominado por el atributo generator.

    • generator: El nombre de @SequenceGenerator que se utilizará. Si omite este atributo, la extensión Hibernate ORM nombra la secuencia según la tabla de la entidad, como movies_SEQ para la tabla movies.

  • @SequenceGenerator define el generador de secuencias:

    • name: El nombre al que hace referencia el atributo @GeneratedValue generator.

    • sequenceName: El nombre del documento de contador. Si lo omite, la extensión Hibernate ORM utiliza el name del generador.

    • initialValue: El valor a partir del cual se genera el primer ID. Por defecto es 1.

    • allocationSize: El número de identificadores reservados en cada bloque.

La extensión Hibernate ORM almacena los documentos de contador en una colección fija llamada hibernate_sequences. Cada secuencia utiliza un documento de contador que tiene los siguientes campos:

  • _id es el nombre de la secuencia.

  • next_value es el valor del contador que la extensión Hibernate ORM incrementa para producir los siguientes ID. Debe coincidir con el initialValue del generador de secuencias, que por defecto es 1.

  • increment es el número de ID reservados a la vez. Debe coincidir con el valor allocationSize del generador de secuencias. Si no coincide, SessionFactory no se inicia.

La extensión Hibernate ORM obtiene los ID en bloques. Esto reduce la cantidad de veces que debe contactar con la base de datos. Las solicitudes realizadas simultáneamente reciben cada una un ID diferente.

Importante

Requisitos del documento de contraparte

Tanto next_value como increment deben ser enteros de 64 bits (BSON Int64). Un documento de contador que no contenga alguno de estos campos, o que almacene un valor como un entero de 32 bits, no podrá asignar identificadores. Si la gestión de esquemas está deshabilitada, deberá crear un documento de contador para cada secuencia antes de que su aplicación pueda asignar identificadores.

La gestión de esquemas es la forma en que Hibernate ORM crea los objetos de base de datos que necesitan tus entidades. La extensión de Hibernate ORM la utiliza para crear los documentos de contador para los ID generados por secuencia.

Para habilitar la administración de esquemas, configure la propiedad jakarta.persistence.schema-generation.database.action en su archivo hibernate.properties o persistence.xml. Utilice uno de los siguientes valores:

  • create: Crea los documentos de contador y los conserva cuando se cierra SessionFactory.

  • create-drop: Crea los documentos de contador cuando se abre SessionFactory y los elimina cuando se cierra.

El siguiente ejemplo utiliza create:

jakarta.persistence.schema-generation.database.action=create

Si prefiere desactivar la gestión de esquemas, puede crear manualmente documentos de contador para los ID generados por secuencia. Configure la siguiente propiedad:

jakarta.persistence.schema-generation.database.action=none

Luego, cree un documento de contador en la colección hibernate_sequences para cada secuencia. El _id del documento de contador debe coincidir con el sequenceName del generador de secuencias.

El siguiente ejemplo utiliza el controlador Java de MongoDB para insertar el documento de contador movies_SEQ en la colección hibernate_sequences de la base de datos que usted indique:

// Replace the placeholders with your connection string and database name.
MongoClient client = MongoClients.create("<connection string>");
MongoDatabase database = client.getDatabase("<database name>");
database.getCollection("hibernate_sequences").insertOne(
new Document("_id", "movies_SEQ")
.append("next_value", new BsonInt64(1))
.append("increment", new BsonInt64(50)));

La inserción crea el documento de contador que se muestra. Establezca next_value al initialValue del generador y increment a su allocationSize.

El siguiente ejemplo guarda una nueva entidad Movie e imprime su ID generada. El ID depende del punto de inicio de la secuencia. Para un nuevo contador que comienza en 1, la salida es:

var movie = new Movie();
movie.setTitle("The Matrix");
session.persist(movie);
System.out.println("Movie created with ID: " + movie.getId());

La extensión Hibernate ORM no admite las siguientes estrategias, tipos y configuraciones relacionadas con secuencias:

  • IDENTITY y estrategias de generación de TABLE

  • BigInteger y tipos de identificadores generados BigDecimal

  • Nombres de secuencia o esquemas que contienen un carácter .

  • Nombres de secuencia calificados por un catálogo, como un nombre de tres partes o el atributo catalog.

  • Secuencia options

  • @GenericGenerator y generadores @TableGenerator, generadores personalizados que utilizan una anotación @IdGeneratorType y generadores heredados con nombre como identity, table o increment.

  • Mapeo de una entidad en la colección hibernate_sequences

  • insert ... select declaraciones que requieren asignación en línea de identificadores generados

Para vincular una entidad a más de un campo, defina una clave primaria compuesta. Cree una clase o registro @Embeddable simple que contenga los componentes de la clave. A continuación, anote el campo identificador de su entidad con la anotación @jakarta.persistence.EmbeddedId.

El siguiente elemento incrustable BookId define una clave que consta de un componente publisherId y un componente bookNo:

@Embeddable
public record BookId(long publisherId, long bookNo) {}

La siguiente entidad Book utiliza BookId como su clave primaria:

@Entity(name = "Book")
@Table(name = "books")
public class Book {
@EmbeddedId
private BookId id;
private String title;
public Book() {
}
public Book(BookId id, String title) {
this.id = id;
this.title = title;
}
// Getter and setter methods
}

Debes asignar valores de clave compuesta en tu aplicación antes de persistir una entidad. La extensión Hibernate ORM no genera valores de clave compuesta.

La extensión Hibernate ORM almacena una clave compuesta como un subdocumento _id. La entidad Book precedente produce documentos en el siguiente formato:

{
"_id": { "bookNo": 2, "publisherId": 10 },
"title": "My Book"
}

La extensión Hibernate ORM ordena los componentes del subdocumento _id alfabéticamente por nombre, en lugar de seguir el orden en que se declaran. Este orden es el mismo tanto si se declara el elemento incrustable como una clase como un registro.

Importante

El orden de los componentes afecta la coincidencia de documentos.

MongoDB compara los subdocumentos según el orden de los campos, por lo que dos valores _id que contienen los mismos componentes en un orden diferente no coinciden. Dado que la extensión Hibernate ORM siempre escribe los componentes en el mismo orden, este comportamiento solo le afecta si también lee o escribe estos documentos fuera de la extensión Hibernate ORM, por ejemplo, a través del controlador Java de MongoDB.

La extensión Hibernate ORM lanza una excepción FeatureNotSupportedException cuando se inicia la aplicación si se declara una clave compuesta de alguna de las siguientes maneras:

  • Un identificador no agregado, declarado con la anotación @jakarta.persistence.IdClass o con múltiples atributos @Id. En su lugar, declare la clave con @EmbeddedId.

  • Un identificador @Struct agregado incrustable. En su lugar, utilice un @Embeddable simple.

  • Un componente que no es un valor básico, como un @Embeddable anidado o una colección. Cada componente de una clave compuesta debe ser un valor básico.

  • Una asociación dentro del identificador, incluida la identidad derivada que utiliza la anotación @jakarta.persistence.MapsId.

Tampoco se puede comparar un identificador compuesto completo utilizando un operador de ordenación como > o <. En su lugar, compare los componentes individualmente.

La extensión Hibernate ORM es compatible con documentos incrustados a través de anotaciones ORM Hibernate @Embeddable. Con los documentos incrustados, puedes crear relaciones Uno a Muchos, Muchos a Uno y Uno a Uno dentro de los documentos de MongoDB. Este formato es ideal para representar datos a los que se accede con frecuencia de forma conjunta.

Para representar documentos incrustados, utiliza las anotaciones @Struct y @Embeddable en una clase para crear un objeto agregable @Struct. Luego, incluye el tipo embebible en tu entidad principal como un campo. La extensión ORM de Hibernate admite la incorporación de objetos únicos, arreglos y colecciones de elementos embebibles.

Tip

Para obtener más información sobre embebibles agregados @Struct, consulta @Struct mapeo agregable embebido en la documentación de Hibernate ORM.

Una relación uno a uno se da cuando un registro en una base de datos está asociado exactamente con un registro en otra base de datos. En MongoDB, puede crear una colección con un campo de documento incrustado para modelar una relación Uno a Uno. La extensión Hibernate ORM permite crear campos de documentos incrustados mediante el uso de agregados @Struct embebibles.

El ejemplo define un campo con un tipo embebible agregado @Struct en una entidad similar al ejemplo Definir una Entidad en esta guía. La clase de entidad de muestra Movie.java incluye la siguiente información:

  • @Entity y @Table anotaciones que definen la entidad y la asignan a la colección movies

  • @Id y las anotaciones @ObjectIdGenerator que designan el campo id como la llave primaria

  • Campo de string que representa el título de la película

  • @Struct campos agregados integrables que representan premios de películas e información de los estudios

El siguiente ejemplo representa una relación uno a uno porque cada entidad Movie se asocia con un Awards incrustable y un Studio incrustable:

@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private Awards awards;
private Studio studio;
public Movie(String title, Awards awards, Studio studio) {
this.title = title;
this.awards = awards;
this.studio = studio;
}
public Movie() {
}
// Getter and setter methods
}

El siguiente código de muestra crea un embebible agregado Awards @Struct:

@Embeddable
@Struct(name = "Awards")
public class Awards {
private int wins;
private int nominations;
private String text;
public Awards(int wins, int nominations, String text) {
this.wins = wins;
this.nominations = nominations;
this.text = text;
}
public Awards() {
}
// Getter and setter methods
}

El siguiente código de muestra crea una Studio @Struct agregada incrustable:

@Embeddable
@Struct(name = "Studio")
public class Studio {
private String name;
private String location;
private int foundedYear;
public Studio(String name, String location, int foundedYear) {
this.name = name;
this.location = location;
this.foundedYear = foundedYear;
}
public Studio() {
}
// Getter and setter methods
}

Una relación uno a muchos es cuando un registro en una base de datos está asociado con muchos registros en otra base de datos. En MongoDB, puedes definir un campo de colección que almacene una lista de documentos incrustados para modelar una relación uno a muchos. La extensión Hibernate ORM te permite crear campos de documentos incrustados utilizando una lista de @Struct embebibles agregados.

El ejemplo define un campo que almacena una lista de @Struct agregados embebidos en una entidad similar a la del Ejemplo de definición de entidad de esta guía. La clase de entidad de muestra Movie.java incluye la siguiente información:

  • @Entity y @Table anotaciones que definen la entidad y la asignan a la colección movies

  • @Id y las anotaciones @ObjectIdGenerator que designan el campo id como la llave primaria

  • Campo de string que representa el título de la película

  • Campo de lista que almacena varios Writer @Struct embebidos agregados, lo cual representa información de autor

El siguiente ejemplo representa una relación de uno-a-muchos porque cada entidad Movie está asociada con múltiples componibles Writer:

@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
@Column(name = "_id")
private ObjectId id;
private String title;
private List<Writer> writers;
public Movie(String title, List<Writer> writers) {
this.title = title;
this.writers = writers;
}
public Movie() {
}
// Getter and setter methods
}

El siguiente código de muestra crea una Writer @Struct agregada incrustable:

@Embeddable
@Struct(name = "Writer")
public class Writer {
private String name;
public Writer() {
}
public Writer(String name) {
this.name = name;
}
// Getter and setter methods
}

Puedes anidar un elemento incrustable aplanado dentro de un elemento incrustable agregado @Struct. Un elemento incrustable aplanado es una clase que incluye una anotación @Embeddable pero no una anotación @Struct. La extensión Hibernate ORM almacena los campos de un elemento incrustable aplanado como campos del documento incrustado principal, en lugar de como un documento anidado independiente.

El siguiente código de ejemplo crea un elemento incrustable agregado Studio @Struct que incluye un elemento incrustable aplanado Address como campo:

@Embeddable
@Struct(name = "Studio")
public class Studio {
private String name;
private Address address;
public Studio() {
}
public Studio(String name, Address address) {
this.name = name;
this.address = address;
}
// Getter and setter methods
}

El siguiente código de ejemplo crea el elemento incrustable aplanado Address. La clase omite la anotación @Struct:

@Embeddable
public class Address {
private String city;
private String country;
public Address() {
}
public Address(String city, String country) {
this.city = city;
this.country = country;
}
// Getter and setter methods
}

Cuando se persiste una entidad que incluye un campo Studio, los campos Address se convierten en campos del documento incrustado del campo Studio. El siguiente documento de ejemplo tiene un campo Studio llamado studio que almacena los campos de su elemento incrustable aplanado Address:

{
"_id": { "$oid": "..." },
"title": "Breathless",
"studio": {
"name": "Les Films Impéria",
"city": "Paris",
"country": "France"
}
}

Para aprender a asignar una jerarquía de clases a una colección de MongoDB, consulte la guía "Asignar una jerarquía de herencia de entidades".

Para aprender a usar tus entidades para ejecutar operaciones de base de datos, consulta las siguientes guías en la sección Interactuar con Datos:

Para obtener más información sobre los campos Hibernate ORM, consulte la sección Tipos de mapeo en la documentación de Hibernate ORM.

Para aprender más sobre las entidades de Hibernate ORM, consulta Modelos POJO en la documentación de Hibernate ORM.