Overview
In this guide, you can learn how to use the MongoDB Extension for Hibernate ORM to run native queries on your MongoDB database. Instead of Hibernate Query Language (HQL) or Jakarta Persistence Query Language (JPQL), native queries allow you to use MongoDB Query Language (MQL) to specify your query. MQL is a query syntax designed for interacting with MongoDB's document-based model.
Tip
MongoDB Query Language
To learn more about MQL's syntax and functionality, see MongoDB Query Language Reference in the MongoDB Server manual.
Hibernate ORM's createQuery() method does not support some MongoDB query features.
The createNativeQuery() method allows you to specify database queries in MQL
and bypass some operational limitations of the Hibernate ORM extension.
You can also run queries directly on your MongoClient object for expanded
query functionality.
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 jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; public class Movie { private ObjectId id; private String title; private String plot; private int year; private int runtime; private String[] cast; public Movie(String title, String plot, int year, int runtime, String[] cast) { this.title = title; this.plot = plot; this.year = year; this.runtime = runtime; this.cast = cast; } 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 int getRuntime() { return runtime; } public void setRuntime(int runtime) { this.runtime = runtime; } public String[] getCast() { return cast; } public void setCast(String[] cast) { this.cast = cast; } }
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 tutorial.
Note
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. The examples
in this guide use a Session. To learn more about persistence
contexts, see the Transactions and Sessions guide.
Run Native Queries
To run a native MongoDB query, specify a MongoDB Query Language (MQL) statement that includes the collection to query and your query criteria in an aggregation pipeline.
Tip
Aggregation Pipeline
To learn more about constructing aggregation pipelines and running aggregation operations, see the Aggregation Pipeline reference in the MongoDB Server manual.
MQL statements have the following format:
String mqlSyntax = """ { aggregate: "<collection to query>", pipeline: [ <aggregation pipeline stages> ] } """;
Important
$project Stage Requirements
The aggregation pipeline in your MQL statement must include a $project stage.
To return the query documents as entity instances, you must specify each entity
field other than the primary key field in the $project stage.
Then, pass the MQL statement to the createNativeQuery() method.
You cannot run native queries that use parameter values. Instead, specify
your search terms within the MQL statement.
You can use native queries to perform the following operations:
Filter and Sort Document Fields
This example runs a native query on the sample_mflix.movies collection
by passing an MQL statement to the createNativeQuery() method. The code
specifies the following aggregation pipeline stages:
$match: Filters for documents that have a title field value of"The Parent Trap"$sort: Sorts the matching documents by theiryearfields in descending order$project: Returns each document field defined in theMovieentity
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { title: { $eq: "The Parent Trap" } } }, { $sort: { year: -1 } }, { $project: { title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie movie : results) { System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear()); }
Title: The Parent Trap, Year: 1998 Title: The Parent Trap, Year: 1961
Use Arithmetic Operators
The Hibernate ORM extension does not currently support HQL or JPQL statements that use arithmetic operators. However, you can perform arithmetic operations on your data by using MongoDB's arithmetic operators in an MQL statement.
Tip
Arithmetic Operators
To learn more about Hibernate and MongoDB arithmetic operators, see the following resources:
Numeric arithmetic in the Hibernate ORM query guide
Arithmetic Operators in the MongoDB Server manual
The following example runs a native query on the sample_mflix.movies collection
that performs the following actions:
Specifies a
$matchstage to match documents that have ayearvalue greater than2000and aruntimefield that existsSpecifies an
$addFieldsstage to add a new field calledruntimeHoursUses the
$dividearithmetic operator to convert theruntimevalue from minutes to hours for the newruntimeHoursfieldSpecifies a
$projectstage to return each document field defined in theMovieentity, other than the primary key fieldPrints the
titlevalue of each updated document
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $match: { year: { $gt: 2000 }, runtime: { $exists: true } } }, { $addFields: { runtimeHours: { $divide: [ "$runtime", 60 ] } }}, { $project: { title: 1, plot: 1, year: 1, runtime: 1, cast: 1 }} ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie result : results) { System.out.println("Added field to movie: " + result.getTitle()); }
Added field to movie: Kate & Leopold Added field to movie: Crime and Punishment Added field to movie: Glitter Added field to movie: The Manson Family Added field to movie: The Dancer Upstairs Added field to movie: Fantastic Four ...
Run a MongoDB Search Query
You can run native queries to perform MongoDB Search queries on your database, which are fine-grained text searches on your data. These queries provide advanced search functionality, such as matching text phrases, scoring results for relevance, and highlighting matches.
Important
You cannot run a MongoDB Search query inside a transaction.
To specify a Search query, create a Search index that covers the fields you want to query.
Then, pass an aggregation pipeline to your createNativeQuery() method that includes a
$search or $searchMeta stage.
Tip
MongoDB Search
To learn more about MongoDB Search queries and indexes, see MongoDB Search Overview in the MongoDB Server manual.
This example runs a Search query by passing the $search pipeline
stage to the createNativeQuery() method. The code performs the following
actions:
Specifies the Search index that covers the
plotfield. Ensure that you replace the<indexName>placeholder with your Search index name.Queries for documents whose
plotvalues contain the string"whirlwind romance"with no more than3words between themSpecifies a
$projectstage to return each document field defined in theMovieentity, other than the primary key fieldPrints the
titleandplotvalues of the matching documents
String nativeQuery = """ { aggregate: "movies", pipeline: [ { $search: { index: "<indexName>", phrase: { path: "plot", query: "whirlwind romance", slop: 3 } } }, { $project: { title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } } ] } """; var results = session.createNativeQuery(nativeQuery, Movie.class) .getResultList(); for (Movie result : results) { System.out.println("Title: " + result.getTitle() + ", Plot: " + result.getPlot()); }
Title: Tokyo Fiancèe, Plot: A young Japanophile Belgian woman in Tokyo falls into a whirlwind romance with a Francophile Japanese student. Title: Designing Woman, Plot: A sportswriter and a fashion-designer marry after a whirlwind romance, and discover they have little in common. Title: Vivacious Lady, Plot: On a quick trip to the city, young university professor Peter Morgan falls in love with nightclub performer Francey Brent and marries her after a whirlwind romance. But when he goes back ... Title: Ek Hasina Thi, Plot: A woman falls for a charming and mysterious businessman. The whirlwind romance turns sour when she is framed for his underworld crimes. Now, finally out of prison she is ready for sweet revenge. Title: Kick, Plot: An adrenaline junkie walks away from a whirlwind romance and embraces a new life as a thief, though he soon finds himself pursued by veteran police officer and engaged in a turf war with a local gangster. Title: A Tale of Winter, Plot: Felicie and Charles have a serious if whirlwind holiday romance. Due to a mix-up on addresses they lose contact, and five years later at Christmas-time Felicie is living with her mother in ...
Run MongoClient Operations
If you want to run database operations that neither the createQuery() method
nor the createNativeQuery() method supports, you can operate on a
MongoClient object directly in your Java application. When working
with the MongoClient, you can access the MongoDB Java Sync Driver's functionality.
Tip
Feature Support
To learn more about unsupported MongoDB features that you must use a
MongoClient object to access, see the Hibernate ORM Feature Compatibility
page.
To learn how to use the Java driver to interact with MongoDB, see the MongoDB Java Driver documentation.
Create Indexes with the MongoClient
You cannot use the Hibernate ORM extension to create indexes on a collection, but you can
instantiate a MongoClient and use the Java driver's createIndex() method. The
following code creates a title field index on the sample_mflix.movies collection:
// Replace the <connection URI> placeholder with your MongoDB connection URI String uri = "<connection URI>"; MongoClient mongoClient = MongoClients.create(uri); MongoDatabase db = mongoClient.getDatabase("sample_mflix"); MongoCollection<Document> collection = db.getCollection("movies"); String indexResult = collection.createIndex(Indexes.ascending("title")); System.out.println(String.format("Index created: %s", indexResult));
Index created: title_1
To learn more about how to use the Java driver to create indexes, see the Indexes guide in the Java driver documentation.
Additional Information
To learn more about the query languages discussed in this guide, see the following resources:
A Guide to Hibernate Query Language in the Hibernate ORM documentation
MongoDB Query Language Reference in the MongoDB Server manual