Hibernate offers an API for creating a representation of a query, adjusting that representation programmatically, and then creating an executable form of the query. The idea is similar in concept to criteria queries, but focused on ease-of-use and less verbosity.
There is support for both selection and mutation queries via the SelectionSpecification
and MutationSpecification
contracts, respectively. These can be obtained from both Session
and StatelessSession
.
Note
|
These APIs are new in 7.0 and considered incubating. |
A SelectionSpecification
allows to iteratively build a query from a "base", adjust the query by adding sorting and restrictions and finally creating an executable SelectionQuery
. We can use HQL as the base -
SelectionSpecification<Book> spec = session.createSelectionSpecification(
"from Book",
Book.class
);
or a root entity as the base -
SelectionSpecification<Book> spec = session.createSelectionSpecification(Book.class);
Once we have the SelectionSpecification
we can adjust the query adding restrictions and sorting -
// from here we can augment the base query "from Book",
// with either restrictions
spec.restriction(
Restriction.restrict(
Book_.suggestedCost,
Range.closed(10.00, 19.99)
)
);
// or here with some sorting
spec.order(
Order.asc(Book_.suggestedCost)
)
Note
|
Notice that generally the JPA static metamodel is a convenient and type-safe way to help build these sorting and restriction references. |
After adjusting the query, we can obtain the executable SelectionQuery
:
SelectionQuery<Book> qry = ds.createQuery();
List<Book> books = qry.getResultList();
These calls can even be chained, e.g.
SelectionQuery<Book> qry = session.createSelectionSpecification(
"from Book",
Book.class
).restriction(
Restriction.restrict(
Book_.suggestedCost,
Range.closed(10.00, 19.99)
)
).order(
Order.asc(Book_.suggestedCost)
).createQuery();
Note
|
We expect, in future releases, to add the ability to handle pagination. We also expect to add the ability to use Criteria references as the base. Possibly even |
There is also support for mutation queries through MutationSpecification
.
At the moment, only update and delete queries are supported. E.g.
MutationQuery<Book> qry = session.createMutationSpecification(
"delete Book",
Book.class
).restriction(
Restriction.restrict(
Book_.suggestedCost,
Range.closed(10.00, 19.99)
)
).createQuery();