crud

For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!-- Tab options on this page. Append to the .md URL to filter: ?tabs=<id,...> select specific tabs (e.g. ?tabs=nodejs,shell) ?allTabs=true include every tab (no param) default: one tab per tabset

Available tabs: other tabs: session, entitymanager -->

Perform CRUD Operations

Overview

In this guide, you can learn how to use the MongoDB Extension for Hibernate ORM to run create, read, update, and delete (CRUD) operations on your MongoDB collections.

Sample Data

The examples in this guide use the Movie entity, which represents the sample_mflix.movies collection from the Atlas sample datasets. The Movie entity has the following definition:

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;
   }
}

To learn how to create a Java application that uses the MongoDB Extension for Hibernate ORM to interact with this MongoDB sample collection, see the [Get Started](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/get-started.md#std-label-hibernate-get-started tutorial.

Important: Persistence Contexts

To enable Hibernate ORM to interact with the database, you must run operations inside a persistence context by using a Hibernate Session or a Jakarta Persistence EntityManager. You also must run write operations inside a transaction to modify MongoDB data and maintain data integrity.

Before running the examples in this guide, ensure that you add persistence context and transaction management code to your application that resembles the following code:

Session

var sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();

// ... Perform CRUD operations here

tx.commit();
session.close();
sf.close();

To use a session, you must create a HibernateUtil.java file that configures a SessionFactory. To learn more, see the [Configure your Application](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/get-started.md#std-label-hibernate-configure-application step of the Get Started tutorial.

Insert Documents

Create a document by passing an entity instance to to the following methods, which insert the corresponding document into your collection:

  • org.hibernate.Session.persist(): Use the Hibernate API to apply your changes to the database

  • jakarta.persistence.EntityManager.persist(): Use the Jakarta Persistence API to apply your changes to the database

Tip:

To learn more about creating entity instances and persisting them to your database, see [Making entities persistent](https://docs.jboss.org/hibernate/orm/7.4/userguide/html_single/Hibernate_User_Guide.html#pc-persist in the Hibernate ORM user guide.

Example

The following example creates a new Movie entity instance and uses the persist() method to insert a corresponding document into the sample_mflix.movies collection:

Session

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);

Read Documents

To retrieve documents from your collection, pass your query criteria to the createQuery() method. The following APIs both provide the createQuery() method:

  • Hibernate's Session API: Use Hibernate Query Language (HQL) syntax to define your queries

  • Jakarta Persistence's EntityManager API: Use Jakarta Persistence Query Language (JPQL) syntax, a subset of HQL, to define your queries

Tip:

To learn more about retrieving data by using HQL and JPQL syntax, see [Select statements](https://docs.jboss.org/hibernate/orm/7.4/querylanguage/html_single/Hibernate_Query_Language.html#select in the Hibernate ORM query guide.

Note:

This section describes how to read documents by using HQL and JPQL, but you can also use the criteria builder or native queries to retrieve data. To learn more, see the following guides:

  • [Specify a Query](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/specify-a-query.md#std-label-hibernate-specify-query

  • [Perform Native Database Queries](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/native-queries.md#std-label-hibernate-native-queries

Return One Document Example

To retrieve only one document that matches your query criteria, chain the getSingleResult() method to the createQuery() method. The following example retrieves one document that has a title value of “Boyhood” from the sample_mflix.movies collection:

Session

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

Output:

Title: Boyhood, Year: 2014

Tip: Query Syntax

To learn more about HQL and JPQL syntax, see A Guide to Hibernate Query Language in the Hibernate ORM documentation.

Return Multiple Documents Example

The following example calls the createQuery() method on a session to retrieve documents from the sample_mflix.movies collection. The code uses HQL and JPQL to return documents that have a year value of 1920 and prints their title values:

Session

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

Output:

High and Dizzy
One Week
The Saphead
The Daughter of Dawn

Modify Documents

You can perform the following operations to modify documents in a collection:

  • [Update one document](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/crud.md#std-label-hibernate-crud-modify-one: Call your entity's setter methods to change field values of one entity instance, and then use a session or entity manager to persist your changes.

  • [Update multiple documents](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/crud.md#std-label-hibernate-crud-modify-many: Pass an update statement to the createQuery() or createMutationQuery() methods on a session or entity manager. Then, call the executeUpdate() method to apply your changes to the database.

Tip:

To learn more about modifying data by using Hibernate ORM, see the following resources:

  • [Modifying managed/persistent state](https://docs.jboss.org/hibernate/orm/7.4/userguide/html_single/Hibernate_User_Guide.html#pc-managed-state in the Hibernate ORM user guide

  • [Update statements](https://docs.jboss.org/hibernate/orm/7.4/querylanguage/html_single/Hibernate_Query_Language.html#update in the Hibernate ORM query guide

Update One Example

The following example retrieves a document by its ObjectId value. Then, the example calls the Movie entity's setTitle() method to update the document's title value to “Jurassic Park I”:

Session

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

Update Multiple Example

The following example updates the title value of matching documents from “The Three Stooges” to “The 3 Stooges”. Then, the example calls the executeUpdate() method to apply the changes to the database:

Session

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);

Output:

Number of movies updated: 2

The SET clause of a bulk update statement can also use an expression instead of a literal value. The expression can reference the field being updated or another field on the entity.

The following example uses an arithmetic expression to increment the year value of documents that have a title value of “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);

Output:

Number of movies updated: 2

The following example uses a field reference to set the plot value to match the title value for documents that have a year value of 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);

Output:

Number of movies updated: 4

Update Multiple Based On Conditional Logic Example

The following example uses a CASE expression to set the plot value depending on whether each document's year value is after the year 2000. The Hibernate ORM extension translates the CASE expression to the MongoDB $switch operator and applies the update by using a $set pipeline stage:

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);

Output:

Number of movies updated: 2

To learn more about CASE expressions, see the [Use Case Expressions for Conditional Logic](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/specify-a-query.md#std-label-hibernate-query-case section in the Specify a Query guide.

Upsert Documents

An upsert operation updates a document if a matching document exists, or inserts a new document if no match exists. To perform an upsert, use the upsert() or upsertMultiple() method. These methods are available only on Hibernate's StatelessSession API.

Note:

A StatelessSession instance does not track changes to the entities it retrieves. To save changes to an entity, pass it to another write method. Use StatelessSession for bulk write workflows.

Entity Requirements

The Hibernate ORM extension creates the filter for an upsert operation from your entity's identifier, so your application must assign the identifier value before you call upsert().

The upsert() method does not generate identifier values, even if your entity uses the @ObjectIdGenerator annotation. If you do not assign an identifier value, the Hibernate ORM extension stores the document with a null _id value.

You can use the @Column(updatable = false) annotation to protect a field from updates during an upsert operation. The following Movie entity definition annotates the released field with @Column(updatable = false), which instructs the Hibernate ORM extension to write to the field when it inserts a document but to omit the field when it updates an existing document:

@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
}

The Hibernate ORM extension sends fields that are both insertable and updatable in the $set operator of the generated update statement. It sends insertable-only fields, such as fields annotated with @Column(updatable = false), in the $setOnInsert operator.

Upsert One Example

The following example creates a Movie entity instance and passes it to the upsert() method. If a document that has the specified ObjectId value exists, the Hibernate ORM extension updates the title and year values of that document. Otherwise, the Hibernate ORM extension inserts a new document:

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);
}

Upsert Multiple Example

To upsert several entity instances in one operation, pass a list of instances to the upsertMultiple() method. The following example upserts two Movie entity instances:

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));
}

Upsert Limitations

The following entity mappings are unsupported in upsert operations. When you upsert an entity that uses one of these mappings, the Hibernate ORM extension throws a FeatureNotSupportedException:

  • Entities that have a field annotated with @Version.

  • Entities that have a field annotated with @Column(insertable = false). MongoDB Query Language provides no way to write a field only when an operation matches an existing document.

  • Entities whose only persistent attribute is the identifier. An upsert on this type of entity has no fields to update, so the Hibernate ORM extension rejects the operation.

Delete Documents

You can perform the following operations to delete documents from a collection:

  • [Delete one document](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/crud.md#std-label-hibernate-crud-delete-one: Call the remove() method on a session or entity manager, passing the entity instance that you want to delete as an argument.

  • [Delete multiple documents](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/crud.md#std-label-hibernate-crud-delete-many: Pass a delete statement to the createQuery() or createMutationQuery() methods on a session or entity manager. Then, call the executeUpdate() method to apply your changes to the database.

Tip:

To learn more about deleting data by using Hibernate ORM, see the following resources:

  • [Deleting entities](https://docs.jboss.org/hibernate/orm/7.4/userguide/html_single/Hibernate_User_Guide.html#pc-remove in the Hibernate ORM user guide

  • [Delete statements](https://docs.jboss.org/hibernate/orm/7.4/querylanguage/html_single/Hibernate_Query_Language.html#delete in the Hibernate ORM query guide

Delete One Example

The following example retrieves a document by its ObjectId value. Then, the example calls the remove() method on a session to delete the corresponding document from the sample_mflix.movies collection:

Session

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

Delete Multiple Example

The following example deletes all documents that have a year value of 1920 from the sample_mflix.movies collection. The example passes a delete statement to the createMutationQuery() method, and then calls the executeUpdate() method to apply the changes to the database:

Session

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

Output:

Number of movies deleted: 4

Additional Information

To learn more about performing CRUD operations by using the Hibernate ORM, see the following resources:

  • [Persistence Context](https://docs.jboss.org/hibernate/orm/7.4/userguide/html_single/Hibernate_User_Guide.html#pc in the Hibernate ORM user guide

  • [Statement types](https://docs.jboss.org/hibernate/orm/7.4/querylanguage/html_single/Hibernate_Query_Language.html#statement-types in the Hibernate ORM query guide

To view more create, read, update, and delete examples, see the following sections of the Get Started tutorial:

  • [Run a Sample Query](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/get-started.md#std-label-hibernate-run-sample-query

  • [Write Data to MongoDB](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/get-started.md#std-label-hibernate-write-data

To learn more about using the Hibernate ORM extension to run queries, see the following guides:

  • [Specify a Query](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/specify-a-query.md#std-label-hibernate-specify-query

  • [Perform Native Database Queries](https://www.mongodb.com/docs/languages/java/mongodb-hibernate/current/interact-data/native-queries.md#std-label-hibernate-native-queries