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

Realizar operaciones CRUD

En esta guía, aprenderás a usar la Extensión MongoDB para Hibernate ORM para ejecutar operaciones de crear, leer, actualizar y borrar (CRUD) en tus colecciones MongoDB.

Los ejemplos de esta guía utilizan la entidad Movie, que representa la colección sample_mflix.movies del conjuntos de datos de muestras de Atlas. La entidad Movie tiene la siguiente definición:

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import java.time.Instant;
import java.util.List;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
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;
private Instant released;
@Embedded
private Awards awards;
@OneToMany(mappedBy = "movie", fetch = FetchType.LAZY)
private List<Comment> comments;
public Movie(String title, String plot, int year, List<String> cast, List<String> directors, Instant released, Awards awards) {
this.title = title;
this.plot = plot;
this.year = year;
this.cast = cast;
this.directors = directors;
this.released = released;
this.awards = awards;
}
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;
}
public Awards getAwards() {
return awards;
}
public void setAwards(Awards awards) {
this.awards = awards;
}
public Instant getReleased() {
return released;
}
public void setReleased(Instant released) {
this.released = released;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
}

Para aprender a crear una aplicación Java que utilice la extensión MongoDB para Hibernate ORM para interactuar con esta colección de muestra de MongoDB, consulta el tutorial Primeros pasos.

Importante

Contextos de Persistencia

Para habilitar que Hibernate ORM interactúe con la base de datos, debes ejecutar operaciones dentro de un contexto de persistencia usando un Hibernate Session o una Persistencia Jakarta EntityManager. También debes ejecutar operaciones de guardar dentro de una transacción para modificar datos de MongoDB y mantener la integridad de los datos.

Antes de ejecutar los ejemplos en esta guía, asegúrate de añadir código de contexto de persistencia y gestión de transacciones a tu aplicación que se asemeje al siguiente código:

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
// ... Perform CRUD operations here
tx.commit();
session.close();
sf.close();

Para utilizar una sesión, debes crear un archivo HibernateUtil.java que configure un SessionFactory. Para obtener más información, consulta el paso Configura tu aplicación del tutorial Comenzar.

// Replace <persistence unit> with the name of your persistence unit in the persistence.xml file
EntityManagerFactory emf = Persistence.createEntityManagerFactory("<persistence unit>");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// ... Perform CRUD operations here
entityManager.getTransaction().commit();
entityManager.close();
emf.close;

Para usar un EntityManager, debes crear un archivo persistence.xml que declare una unidad de persistencia. Para aprender más, consulta el Tutorial utilizando APIs estándar JPA en la documentación de Hibernate ORM.

Crea un documento pasando una instancia de entidad a los siguientes métodos, que insertan el documento correspondiente en tu colección:

  • org.hibernate.Session.persist(): Utiliza la API de Hibernate para aplicar tus cambios a la base de datos

  • jakarta.persistence.EntityManager.persist(): Usa la API de persistencia de Jakarta para aplicar tus cambios a la base de datos

Tip

Para obtener más información sobre la creación de instancias de entidades y su persistencia en la base de datos, consulta Haciendo persistentes las entidades en la guía para usuarios de Hibernate ORM.

El siguiente ejemplo crea una nueva instancia de entidad Movie y utiliza el método persist() para insertar un documento correspondiente en la colección sample_mflix.movies:

var myMovie = new Movie();
myMovie.setTitle("Knives Out");
myMovie.setYear(2019);
myMovie.setCast(List.of("Ana de Armas", "Daniel Craig", "Chris Evans"));
myMovie.setPlot("Detective Benoit Blanc investigates the mysterious death of crime novelist Harlan Thrombey, " +
"unraveling lies as every Thrombey family member becomes a suspect.");
session.persist(myMovie);
var myMovie = new Movie();
myMovie.setTitle("Knives Out");
myMovie.setYear(2019);
myMovie.setCast(List.of("Ana de Armas", "Daniel Craig", "Chris Evans"));
myMovie.setPlot("Detective Benoit Blanc investigates the mysterious death of crime novelist Harlan Thrombey, " +
"unraveling lies as every Thrombey family member becomes a suspect.");
entityManager.persist(myMovie);

Para recuperar documentos de tu colección, proporciona los criterios de tu query al método createQuery(). Las siguientes APIs proporcionan el método createQuery():

  • API Session de Hibernate: Usa la sintaxis de Hibernate Query Language (HQL) para definir tus consultas

  • API EntityManager de Jakarta Persistence: Usa la sintaxis de Jakarta Persistence Query Language (JPQL), que es un subconjunto de HQL, para definir tus consultas.

Tip

Para obtener más información sobre cómo aprender a recuperar datos utilizando la sintaxis HQL y JPQL, consulta Instrucciones select en la guía de query Hibernate ORM.

Nota

Esta sección describe cómo leer documentos utilizando HQL y JPQL, pero también se puede utilizar el generador de criterios o consultas nativas para recuperar datos. Para obtener más información, consulta las siguientes guías:

Para recuperar solo un documento que coincida con tus criterios de query, encadena el método getSingleResult() al método createQuery(). El siguiente ejemplo recupera un documento que tiene un valor de title de "Boyhood" de la colección sample_mflix.movies:

var singleResult = session.createQuery("from Movie where title = :t", Movie.class)
.setParameter("t", "Boyhood")
.getSingleResult();
System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());
var singleResult = entityManager.createQuery("select m from Movie m where m.title = :t", Movie.class)
.setParameter("t", "Boyhood")
.getSingleResult();
System.out.println("Title: " + singleResult.getTitle() + ", Year: " + singleResult.getYear());

Tip

Query sintaxis

Para obtener más información sobre la sintaxis de HQL y JPQL, consulta Una guía sobre Hibernate languaje del query en la documentación de Hibernate ORM.

El siguiente ejemplo llama al método createQuery() en una sesión para recuperar documentos de la colección sample_mflix.movies. El código utiliza HQL y JPQL para devolver documentos que tienen un valor de year igual a 1920 e imprime sus valores de title:

var results = session.createQuery("from Movie where year = :y", Movie.class)
.setParameter("y", 1920)
.getResultList();
results.forEach(movie -> System.out.println(movie.getTitle()));
var results = entityManager.createQuery("select m from Movie m where m.year = :y", Movie.class)
.setParameter("y", 1920)
.getResultList();
results.forEach(movie -> System.out.println(movie.getTitle()));

Puedes realizar las siguientes operaciones para modificar documentos en una colección:

  • Actualizar un documento: Llama a los métodos setter de tu entidad para cambiar los valores de los campos de una instancia de entidad y luego utiliza una sesión o un administrador de entidades para guardar tus cambios.

  • Actualizar documentos múltiples: Pasa una instrucción de actualizar a los métodos createQuery() o createMutationQuery() en una sesión o administrador de entidades. Luego, llama al método executeUpdate() para aplicar tus cambios a la base de datos.

Tip

Para obtener más información sobre cómo modificar datos utilizando Hibernate ORM, consulta los siguientes recursos:

El siguiente ejemplo recupera un documento por su valor ObjectId. Luego, el ejemplo llama al método setTitle() de la entidad Movie para actualizar el valor title del documento a "Jurassic Park I":

// Your ObjectId value might differ
Movie movieById = session.get(Movie.class, new ObjectId("573a1399f29313caabcedc5d"));
movieById.setTitle("Jurassic Park I");
session.persist(movieById);
// Your ObjectId value might differ
Movie movieById = entityManager.find(Movie.class, new ObjectId("573a1399f29313caabcedc5d"));
movieById.setTitle("Jurassic Park I");
entityManager.persist(movieById);

El siguiente ejemplo actualiza el valor de title de los documentos coincidentes de "The Three Stooges" a "The 3 Stooges". Luego, el ejemplo llama al método executeUpdate() para aplicar los cambios a la base de datos:

var updateResult = session.createMutationQuery(
"update Movie set title = :new where title = :old")
.setParameter("new", "The 3 Stooges")
.setParameter("old", "The Three Stooges")
.executeUpdate();
System.out.println("Number of movies updated: " + updateResult);
var updateResult = entityManager.createQuery(
"update Movie m set m.title = :new where m.title = :old")
.setParameter("new", "The 3 Stooges")
.setParameter("old", "The Three Stooges")
.executeUpdate();
System.out.println("Number of movies updated: " + updateResult);

La cláusula SET de una instrucción de actualización masiva también puede usar una expresión en lugar de un valor literal. La expresión puede hacer referencia al campo que se está actualizando o a otro campo de la entidad.

El siguiente ejemplo utiliza una expresión aritmética para incrementar el valor year de los documentos que tienen un valor title igual a "The 3 Stooges":

var updateResult = session.createMutationQuery(
"update Movie m set m.year = m.year + 1 where m.title = :title")
.setParameter("title", "The 3 Stooges")
.executeUpdate();
System.out.println("Number of movies updated: " + updateResult);

El siguiente ejemplo utiliza una referencia de campo para establecer el valor plot para que coincida con el valor title para los documentos que tienen un valor year de 1920:

var updateResult = session.createMutationQuery(
"update Movie m set m.plot = m.title where m.year = :year")
.setParameter("year", 1920)
.executeUpdate();
System.out.println("Number of movies updated: " + updateResult);

El siguiente ejemplo utiliza una expresión CASE para establecer el valor plot dependiendo de si el valor year de cada documento es posterior al año 2000. La extensión Hibernate ORM traduce la expresión CASE al operador $switch de MongoDB y aplica la actualización mediante una etapa de canalización $set:

var updateResult = session.createMutationQuery(
"update Movie m set m.plot = case when m.year > 2000 then 'Modern release' "
+ "else 'Classic release' end where m.title = :title")
.setParameter("title", "The 3 Stooges")
.executeUpdate();
System.out.println("Number of movies updated: " + updateResult);

Para obtener más información sobre las expresiones CASE, consulte la sección Expresiones de casos de uso para lógica condicional en la guía Especificar una consulta.

Una operación de inserción o actualización (upsert) actualiza un documento si existe uno coincidente, o inserta uno nuevo si no existe ninguno. Para realizar una operación upsert, utilice el método upsert() o upsertMultiple(). Estos métodos solo están disponibles en la API StatelessSession de Hibernate.

Nota

Una instancia StatelessSession no registra los cambios en las entidades que recupera. Para guardar los cambios en una entidad, pásela a otro método de escritura. Utilice StatelessSession para flujos de trabajo de escritura masiva.

La extensión Hibernate ORM crea el filtro para una operación upsert a partir del identificador de su entidad, por lo que su aplicación debe asignar el valor del identificador antes de llamar a upsert().

El método upsert() no genera valores de identificador, incluso si su entidad utiliza la anotación @ObjectIdGenerator. Si no asigna un valor de identificador, la extensión Hibernate ORM almacena el documento con un valor null _id.

Puedes usar la anotación @Column(updatable = false) para proteger un campo de las actualizaciones durante una operación de inserción/actualización. La siguiente definición de entidad Movie anota el campo released con @Column(updatable = false), lo que indica a la extensión ORM de Hibernate que escriba en el campo cuando inserte un documento, pero que lo omita cuando actualice un documento existente:

@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private int year;
@Column(updatable = false)
private Instant released;
// Getters and setters omitted
}

La extensión Hibernate ORM envía los campos que son tanto insertables como actualizables en el operador $set de la instrucción de actualización generada. Envía los campos que solo son insertables, como los campos anotados con @Column(updatable = false), en el operador $setOnInsert.

El siguiente ejemplo crea una instancia de entidad Movie y la pasa al método upsert(). Si existe un documento con el valor ObjectId especificado, la extensión Hibernate ORM actualiza los valores title y year de dicho documento. De lo contrario, la extensión Hibernate ORM inserta un nuevo documento.

try (StatelessSession statelessSession = sf.openStatelessSession()) {
var movie = new Movie();
movie.setId(new ObjectId("573a1398f29313caabce9682"));
movie.setTitle("The General");
movie.setYear(1926);
movie.setReleased(Instant.parse("1927-02-24T00:00:00Z"));
statelessSession.upsert(movie);
}

Para insertar o actualizar varias instancias de entidad en una sola operación, pase una lista de instancias al método upsertMultiple(). El siguiente ejemplo inserta o actualiza dos instancias de entidad Movie:

try (StatelessSession statelessSession = sf.openStatelessSession()) {
var firstMovie = new Movie();
firstMovie.setId(new ObjectId("573a1398f29313caabce9682"));
firstMovie.setTitle("The General");
firstMovie.setYear(1926);
var secondMovie = new Movie();
secondMovie.setId(new ObjectId("573a1398f29313caabce9683"));
secondMovie.setTitle("Metropolis");
secondMovie.setYear(1927);
statelessSession.upsertMultiple(List.of(firstMovie, secondMovie));
}

Las siguientes asignaciones de entidades no son compatibles con las operaciones de inserción/actualización. Cuando se inserta/actualiza una entidad que utiliza una de estas asignaciones, la extensión Hibernate ORM genera un error FeatureNotSupportedException:

  • Entidades que tienen un campo anotado con @Version.

  • Entidades que tienen un campo anotado con @Column(insertable = false). El lenguaje de consulta de MongoDB no proporciona ninguna forma de escribir un campo solo cuando una operación coincide con un documento existente.

  • Entidades cuyo único atributo persistente es el identificador. Una operación de actualización o inserción en este tipo de entidad no tiene campos que actualizar, por lo que la extensión Hibernate ORM rechaza la operación.

Puedes realizar las siguientes operaciones para borrar documentos de una colección:

  • Borrar un documento: Llama al método remove() en una sesión o administrador de entidades, pasando la instancia de entidad que deseas borrar como argumento.

  • Eliminar varios documentos: Proporcione una instrucción de borrado a los métodos createQuery() o createMutationQuery() en una sesión o administrador de entidades. A continuación, llama al método executeUpdate() para aplicar los cambios a la base de datos.

Tip

Para obtener más información sobre el borrado de datos con Hibernate ORM, consulta los siguientes recursos:

El siguiente ejemplo recupera un documento por su valor de ObjectId. Luego, el ejemplo llama al método remove() en una sesión para borrar el documento correspondiente de la colección sample_mflix.movies:

// Your ObjectId value might differ
Movie movieToDelete = session.get(Movie.class, new ObjectId("573a1399f29313caabcedc5d"));
session.remove(movieToDelete);
// Your ObjectId value might differ
Movie movieToDelete = entityManager.find(Movie.class, new ObjectId("573a1399f29313caabcedc5d"));
entityManager.remove(movieToDelete);

El siguiente ejemplo elimina todos los documentos que tienen un valor year de 1920 de la colección sample_mflix.movies. El ejemplo pasa una instrucción de borrado al método createMutationQuery() y luego llama al método executeUpdate() para aplicar los cambios a la base de datos:

var deleteResult = session.createMutationQuery(
"delete Movie where year = :y")
.setParameter("y", 1920)
.executeUpdate();
System.out.println("Number of movies deleted: " + deleteResult);
var deleteResult = entityManager.createQuery(
"delete Movie m where m.year = :y")
.setParameter("y", 1920)
.executeUpdate();
System.out.println("Number of movies deleted: " + deleteResult);

Para obtener más información sobre cómo realizar operaciones CRUD utilizando Hibernate ORM, consulta los siguientes recursos:

Para ver más ejemplos de creación, lectura, actualización y borrar, consulta las siguientes secciones del tutorial Comenzar:

Para obtener más información sobre cómo utilizar la extensión Hibernate ORM para ejecutar consultas, consulta las siguientes guías: