Jakarta Persistence API provides a comprehensive framework for object-relational mapping, entity lifecycle management, and database operations in Java applications
Complete reference for building type-safe queries programmatically using the Criteria API in Jakarta Persistence.
The Criteria API provides a type-safe way to construct JPQL queries programmatically. The main entry point is CriteriaBuilder, which creates query objects and expressions.
import jakarta.persistence.criteria.*;
/**
* Main interface for constructing criteria queries, compound selections, expressions, predicates, and orderings
*/
public interface CriteriaBuilder {
// Query creation
CriteriaQuery<Object> createQuery();
<T> CriteriaQuery<T> createQuery(Class<T> resultClass);
CriteriaQuery<Tuple> createTupleQuery();
<T> CriteriaUpdate<T> createCriteriaUpdate(Class<T> targetEntity);
<T> CriteriaDelete<T> createCriteriaDelete(Class<T> targetEntity);
// Logical operators
Predicate and(Expression<Boolean> x, Expression<Boolean> y);
Predicate and(Predicate... restrictions);
Predicate or(Expression<Boolean> x, Expression<Boolean> y);
Predicate or(Predicate... restrictions);
Predicate not(Expression<Boolean> restriction);
Predicate conjunction();
Predicate disjunction();
// Comparison predicates
Predicate equal(Expression<?> x, Expression<?> y);
Predicate equal(Expression<?> x, Object y);
Predicate notEqual(Expression<?> x, Expression<?> y);
Predicate notEqual(Expression<?> x, Object y);
<Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Expression<? extends Y> y);
<Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Y y);
<Y extends Comparable<? super Y>> Predicate greaterThanOrEqualTo(Expression<? extends Y> x, Expression<? extends Y> y);
<Y extends Comparable<? super Y>> Predicate greaterThanOrEqualTo(Expression<? extends Y> x, Y y);
<Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Expression<? extends Y> y);
<Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Y y);
<Y extends Comparable<? super Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> x, Expression<? extends Y> y);
<Y extends Comparable<? super Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> x, Y y);
<Y extends Comparable<? super Y>> Predicate between(Expression<? extends Y> v, Expression<? extends Y> x, Expression<? extends Y> y);
<Y extends Comparable<? super Y>> Predicate between(Expression<? extends Y> v, Y x, Y y);
Predicate gt(Expression<? extends Number> x, Expression<? extends Number> y);
Predicate gt(Expression<? extends Number> x, Number y);
Predicate ge(Expression<? extends Number> x, Expression<? extends Number> y);
Predicate ge(Expression<? extends Number> x, Number y);
Predicate lt(Expression<? extends Number> x, Expression<? extends Number> y);
Predicate lt(Expression<? extends Number> x, Number y);
Predicate le(Expression<? extends Number> x, Expression<? extends Number> y);
Predicate le(Expression<? extends Number> x, Number y);
// Null predicates
Predicate isNull(Expression<?> x);
Predicate isNotNull(Expression<?> x);
// Collection predicates
Predicate isTrue(Expression<Boolean> x);
Predicate isFalse(Expression<Boolean> x);
<E, C extends Collection<E>> Predicate isMember(Expression<E> elem, Expression<C> collection);
<E, C extends Collection<E>> Predicate isMember(E elem, Expression<C> collection);
<E, C extends Collection<E>> Predicate isNotMember(Expression<E> elem, Expression<C> collection);
<E, C extends Collection<E>> Predicate isNotMember(E elem, Expression<C> collection);
<C extends Collection<?>> Predicate isEmpty(Expression<C> collection);
<C extends Collection<?>> Predicate isNotEmpty(Expression<C> collection);
<C extends Collection<?>> Expression<Integer> size(Expression<C> collection);
<C extends Collection<?>> Expression<Integer> size(C collection);
<V, M extends Map<?, V>> Expression<Collection<V>> values(M map);
<K, M extends Map<K, ?>> Expression<Set<K>> keys(M map);
// String predicates
Predicate like(Expression<String> x, Expression<String> pattern);
Predicate like(Expression<String> x, String pattern);
Predicate like(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar);
Predicate like(Expression<String> x, Expression<String> pattern, char escapeChar);
Predicate like(Expression<String> x, String pattern, Expression<Character> escapeChar);
Predicate like(Expression<String> x, String pattern, char escapeChar);
Predicate notLike(Expression<String> x, Expression<String> pattern);
Predicate notLike(Expression<String> x, String pattern);
Predicate notLike(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar);
Predicate notLike(Expression<String> x, Expression<String> pattern, char escapeChar);
Predicate notLike(Expression<String> x, String pattern, Expression<Character> escapeChar);
Predicate notLike(Expression<String> x, String pattern, char escapeChar);
// In predicates
<T> In<T> in(Expression<? extends T> expression);
CriteriaBuilder.In<Object> in(Expression<?> expression);
// Arithmetic operators
<N extends Number> Expression<N> neg(Expression<N> x);
<N extends Number> Expression<N> abs(Expression<N> x);
<N extends Number> Expression<N> sum(Expression<? extends N> x, Expression<? extends N> y);
<N extends Number> Expression<N> sum(Expression<? extends N> x, N y);
<N extends Number> Expression<N> sum(N x, Expression<? extends N> y);
<N extends Number> Expression<N> prod(Expression<? extends N> x, Expression<? extends N> y);
<N extends Number> Expression<N> prod(Expression<? extends N> x, N y);
<N extends Number> Expression<N> prod(N x, Expression<? extends N> y);
<N extends Number> Expression<N> diff(Expression<? extends N> x, Expression<? extends N> y);
<N extends Number> Expression<N> diff(Expression<? extends N> x, N y);
<N extends Number> Expression<N> diff(N x, Expression<? extends N> y);
Expression<Number> quot(Expression<? extends Number> x, Expression<? extends Number> y);
Expression<Number> quot(Expression<? extends Number> x, Number y);
Expression<Number> quot(Number x, Expression<? extends Number> y);
Expression<Integer> mod(Expression<Integer> x, Expression<Integer> y);
Expression<Integer> mod(Expression<Integer> x, Integer y);
Expression<Integer> mod(Integer x, Expression<Integer> y);
Expression<Double> sqrt(Expression<? extends Number> x);
<N extends Number> Expression<N> ceiling(Expression<N> x);
<N extends Number> Expression<N> floor(Expression<N> x);
Expression<Integer> sign(Expression<? extends Number> x);
Expression<Double> power(Expression<? extends Number> x, Expression<? extends Number> y);
Expression<Double> power(Expression<? extends Number> x, Number y);
Expression<Double> exp(Expression<? extends Number> x);
Expression<Double> ln(Expression<? extends Number> x);
// Aggregate functions
<N extends Number> Expression<Double> avg(Expression<N> x);
<N extends Number> Expression<N> sum(Expression<N> x);
Expression<Long> sumAsLong(Expression<Integer> x);
Expression<Double> sumAsDouble(Expression<Float> x);
<N extends Number> Expression<N> max(Expression<N> x);
<N extends Number> Expression<N> min(Expression<N> x);
<X extends Comparable<? super X>> Expression<X> greatest(Expression<X> x);
<X extends Comparable<? super X>> Expression<X> least(Expression<X> x);
Expression<Long> count(Expression<?> x);
Expression<Long> countDistinct(Expression<?> x);
// String functions
Expression<String> concat(Expression<String> x, Expression<String> y);
Expression<String> concat(Expression<String> x, String y);
Expression<String> concat(String x, Expression<String> y);
Expression<String> substring(Expression<String> x, Expression<Integer> from);
Expression<String> substring(Expression<String> x, int from);
Expression<String> substring(Expression<String> x, Expression<Integer> from, Expression<Integer> len);
Expression<String> substring(Expression<String> x, int from, int len);
Expression<String> trim(Expression<String> x);
Expression<String> trim(Trimspec ts, Expression<String> x);
Expression<String> trim(Expression<Character> t, Expression<String> x);
Expression<String> trim(Trimspec ts, Expression<Character> t, Expression<String> x);
Expression<String> trim(char t, Expression<String> x);
Expression<String> trim(Trimspec ts, char t, Expression<String> x);
Expression<String> lower(Expression<String> x);
Expression<String> upper(Expression<String> x);
Expression<Integer> length(Expression<String> x);
Expression<Integer> locate(Expression<String> x, Expression<String> pattern);
Expression<Integer> locate(Expression<String> x, String pattern);
Expression<Integer> locate(Expression<String> x, Expression<String> pattern, Expression<Integer> from);
Expression<Integer> locate(Expression<String> x, String pattern, int from);
// Date/time functions
Expression<java.sql.Date> currentDate();
Expression<java.sql.Timestamp> currentTimestamp();
Expression<java.sql.Time> currentTime();
// Literals
<T> Expression<T> literal(T value);
<T> Expression<T> nullLiteral(Class<T> resultClass);
// Parameters
<T> ParameterExpression<T> parameter(Class<T> paramClass);
<T> ParameterExpression<T> parameter(Class<T> paramClass, String name);
// Case expressions
<R> Case<R> selectCase();
<C, R> SimpleCase<C, R> selectCase(Expression<? extends C> expression);
<T> Coalesce<T> coalesce();
<Y> Expression<Y> coalesce(Expression<? extends Y> x, Expression<? extends Y> y);
<Y> Expression<Y> coalesce(Expression<? extends Y> x, Y y);
<Y> Expression<Y> nullif(Expression<Y> x, Expression<?> y);
<Y> Expression<Y> nullif(Expression<Y> x, Y y);
// Functions
<T> Expression<T> function(String name, Class<T> type, Expression<?>... args);
// Ordering
Order asc(Expression<?> x);
Order desc(Expression<?> x);
// Tuples
CompoundSelection<Tuple> tuple(Selection<?>... selections);
CompoundSelection<Object[]> array(Selection<?>... selections);
<Y> CompoundSelection<Y> construct(Class<Y> resultClass, Selection<?>... selections);
// Subqueries
Predicate exists(Subquery<?> subquery);
<Y> Expression<Y> all(Subquery<Y> subquery);
<Y> Expression<Y> some(Subquery<Y> subquery);
<Y> Expression<Y> any(Subquery<Y> subquery);
// Treat and type operations
<X, T, V extends T> Join<X, V> treat(Join<X, T> join, Class<V> type);
<X, T, E extends T> CollectionJoin<X, E> treat(CollectionJoin<X, T> join, Class<E> type);
<X, T, E extends T> SetJoin<X, E> treat(SetJoin<X, T> join, Class<E> type);
<X, T, E extends T> ListJoin<X, E> treat(ListJoin<X, T> join, Class<E> type);
<X, K, T, V extends T> MapJoin<X, K, V> treat(MapJoin<X, K, T> join, Class<V> type);
<X, T extends X> Path<T> treat(Path<X> path, Class<T> type);
<X, T extends X> Root<T> treat(Root<X> root, Class<T> type);
// Type
<X, T> Expression<X> type(Root<T> root);
}Usage Example:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);
// Add predicates
Predicate agePredicate = cb.greaterThan(root.get("age"), 18);
Predicate namePredicate = cb.like(root.get("name"), "John%");
query.where(cb.and(agePredicate, namePredicate));
// Order results
query.orderBy(cb.asc(root.get("name")));
List<User> results = entityManager.createQuery(query).getResultList();Interfaces for defining and executing criteria queries.
/**
* The CriteriaQuery interface defines functionality specific to top-level queries
*/
public interface CriteriaQuery<T> extends AbstractQuery<T> {
CriteriaQuery<T> select(Selection<? extends T> selection);
CriteriaQuery<T> multiselect(Selection<?>... selections);
CriteriaQuery<T> multiselect(List<Selection<?>> selectionList);
CriteriaQuery<T> where(Expression<Boolean> restriction);
CriteriaQuery<T> where(Predicate... restrictions);
CriteriaQuery<T> groupBy(Expression<?>... grouping);
CriteriaQuery<T> groupBy(List<Expression<?>> grouping);
CriteriaQuery<T> having(Expression<Boolean> restriction);
CriteriaQuery<T> having(Predicate... restrictions);
CriteriaQuery<T> orderBy(Order... o);
CriteriaQuery<T> orderBy(List<Order> o);
CriteriaQuery<T> distinct(boolean distinct);
List<Order> getOrderList();
Set<ParameterExpression<?>> getParameters();
}
/**
* Base interface for criteria queries and subqueries
*/
public interface AbstractQuery<T> extends CommonAbstractCriteria {
<X> Root<X> from(Class<X> entityClass);
<X> Root<X> from(EntityType<X> entity);
AbstractQuery<T> where(Expression<Boolean> restriction);
AbstractQuery<T> where(Predicate... restrictions);
AbstractQuery<T> groupBy(Expression<?>... grouping);
AbstractQuery<T> groupBy(List<Expression<?>> grouping);
AbstractQuery<T> having(Expression<Boolean> restriction);
AbstractQuery<T> having(Predicate... restrictions);
AbstractQuery<T> distinct(boolean distinct);
Set<Root<?>> getRoots();
Selection<T> getSelection();
List<Expression<?>> getGroupList();
Predicate getGroupRestriction();
boolean isDistinct();
Class<T> getResultType();
}
/**
* Common functionality for all criteria operations
*/
public interface CommonAbstractCriteria {
<U> Subquery<U> subquery(Class<U> type);
Predicate getRestriction();
}
/**
* The Subquery interface defines functionality specific to subqueries
*/
public interface Subquery<T> extends AbstractQuery<T>, Expression<T> {
Subquery<T> select(Expression<T> expression);
Subquery<T> where(Expression<Boolean> restriction);
Subquery<T> where(Predicate... restrictions);
Subquery<T> groupBy(Expression<?>... grouping);
Subquery<T> groupBy(List<Expression<?>> grouping);
Subquery<T> having(Expression<Boolean> restriction);
Subquery<T> having(Predicate... restrictions);
Subquery<T> distinct(boolean distinct);
<Y> Root<Y> correlate(Root<Y> parentRoot);
<X, Y> Join<X, Y> correlate(Join<X, Y> parentJoin);
<X, Y> CollectionJoin<X, Y> correlate(CollectionJoin<X, Y> parentCollection);
<X, Y> SetJoin<X, Y> correlate(SetJoin<X, Y> parentSet);
<X, Y> ListJoin<X, Y> correlate(ListJoin<X, Y> parentList);
<X, K, V> MapJoin<X, K, V> correlate(MapJoin<X, K, V> parentMap);
AbstractQuery<?> getParent();
CommonAbstractCriteria getContainingQuery();
Expression<T> getSelection();
Set<Join<?, ?>> getCorrelatedJoins();
}Criteria API for bulk update and delete operations.
/**
* Interface for performing bulk update operations using Criteria API
*/
public interface CriteriaUpdate<T> extends CommonAbstractCriteria {
Root<T> from(Class<T> entityClass);
Root<T> from(EntityType<T> entity);
Root<T> getRoot();
<Y, X extends Y> CriteriaUpdate<T> set(SingularAttribute<? super T, Y> attribute, X value);
<Y> CriteriaUpdate<T> set(SingularAttribute<? super T, Y> attribute, Expression<? extends Y> value);
<Y, X extends Y> CriteriaUpdate<T> set(Path<Y> attribute, X value);
<Y> CriteriaUpdate<T> set(Path<Y> attribute, Expression<? extends Y> value);
CriteriaUpdate<T> set(String attributeName, Object value);
CriteriaUpdate<T> where(Expression<Boolean> restriction);
CriteriaUpdate<T> where(Predicate... restrictions);
}
/**
* Interface for performing bulk delete operations using Criteria API
*/
public interface CriteriaDelete<T> extends CommonAbstractCriteria {
Root<T> from(Class<T> entityClass);
Root<T> from(EntityType<T> entity);
Root<T> getRoot();
CriteriaDelete<T> where(Expression<Boolean> restriction);
CriteriaDelete<T> where(Predicate... restrictions);
}Usage Example:
// Bulk update
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaUpdate<User> update = cb.createCriteriaUpdate(User.class);
Root<User> root = update.from(User.class);
update.set(root.get("status"), "inactive")
.where(cb.lessThan(root.get("lastLogin"), oldDate));
em.createQuery(update).executeUpdate();
// Bulk delete
CriteriaDelete<User> delete = cb.createCriteriaDelete(User.class);
Root<User> root = delete.from(User.class);
delete.where(cb.equal(root.get("status"), "deleted"));
em.createQuery(delete).executeUpdate();Core expression and predicate types for building query conditions.
/**
* Type for query expressions
*/
public interface Expression<T> extends Selection<T> {
Predicate isNull();
Predicate isNotNull();
Predicate in(Object... values);
Predicate in(Expression<?>... values);
Predicate in(Collection<?> values);
Predicate in(Expression<Collection<?>> values);
<X> Expression<X> as(Class<X> type);
}
/**
* Boolean expressions used in WHERE clauses
*/
public interface Predicate extends Expression<Boolean> {
enum BooleanOperator { AND, OR }
BooleanOperator getOperator();
boolean isNegated();
List<Expression<Boolean>> getExpressions();
Predicate not();
}
/**
* Represents a selection item in the SELECT clause
*/
public interface Selection<X> extends TupleElement<X> {
Selection<X> alias(String name);
boolean isCompoundSelection();
List<Selection<?>> getCompoundSelectionItems();
}
/**
* Compound selection item (tuple, array, or constructor result)
*/
public interface CompoundSelection<X> extends Selection<X> {
// Inherits all methods from Selection<X>
}
/**
* Type of criteria query parameter expressions
*/
public interface ParameterExpression<T> extends Parameter<T>, Expression<T> {
// Combines Parameter and Expression functionality
}Path expressions for navigating to entity attributes.
/**
* Represents a simple or compound attribute path
*/
public interface Path<X> extends Expression<X> {
Bindable<X> getModel();
Path<?> getParentPath();
<Y> Path<Y> get(SingularAttribute<? super X, Y> attribute);
<E, C extends Collection<E>> Expression<C> get(PluralAttribute<X, C, E> collection);
<K, V, M extends Map<K, V>> Expression<M> get(MapAttribute<X, K, V> map);
Expression<Class<? extends X>> type();
<Y> Path<Y> get(String attributeName);
}
/**
* A root type in the from clause that references entities
*/
public interface Root<X> extends From<X, X> {
EntityType<X> getModel();
}
/**
* Represents a bound type appearing in the from clause
*/
public interface From<Z, X> extends Path<X>, FetchParent<Z, X> {
Set<Join<X, ?>> getJoins();
boolean isCorrelated();
From<Z, X> getCorrelationParent();
<Y> Join<X, Y> join(SingularAttribute<? super X, Y> attribute);
<Y> Join<X, Y> join(SingularAttribute<? super X, Y> attribute, JoinType jt);
<Y> CollectionJoin<X, Y> join(CollectionAttribute<? super X, Y> collection);
<Y> SetJoin<X, Y> join(SetAttribute<? super X, Y> set);
<Y> ListJoin<X, Y> join(ListAttribute<? super X, Y> list);
<K, V> MapJoin<X, K, V> join(MapAttribute<? super X, K, V> map);
<Y> CollectionJoin<X, Y> join(CollectionAttribute<? super X, Y> collection, JoinType jt);
<Y> SetJoin<X, Y> join(SetAttribute<? super X, Y> set, JoinType jt);
<Y> ListJoin<X, Y> join(ListAttribute<? super X, Y> list, JoinType jt);
<K, V> MapJoin<X, K, V> join(MapAttribute<? super X, K, V> map, JoinType jt);
<X, Y> Join<X, Y> join(String attributeName);
<X, Y> CollectionJoin<X, Y> joinCollection(String attributeName);
<X, Y> SetJoin<X, Y> joinSet(String attributeName);
<X, Y> ListJoin<X, Y> joinList(String attributeName);
<X, K, V> MapJoin<X, K, V> joinMap(String attributeName);
<X, Y> Join<X, Y> join(String attributeName, JoinType jt);
<X, Y> CollectionJoin<X, Y> joinCollection(String attributeName, JoinType jt);
<X, Y> SetJoin<X, Y> joinSet(String attributeName, JoinType jt);
<X, Y> ListJoin<X, Y> joinList(String attributeName, JoinType jt);
<X, K, V> MapJoin<X, K, V> joinMap(String attributeName, JoinType jt);
}Join interfaces for navigating relationships.
/**
* A join to an entity, embeddable, or basic type
*/
public interface Join<Z, X> extends From<Z, X> {
Join<Z, X> on(Expression<Boolean> restriction);
Join<Z, X> on(Predicate... restrictions);
Predicate getOn();
Attribute<? super Z, ?> getAttribute();
From<?, Z> getParent();
JoinType getJoinType();
}
/**
* Common functionality for joins to all collection types
*/
public interface PluralJoin<Z, C, E> extends Join<Z, E> {
PluralAttribute<? super Z, C, E> getModel();
}
/**
* Join to a java.util.Collection
*/
public interface CollectionJoin<Z, E> extends PluralJoin<Z, Collection<E>, E> {
CollectionJoin<Z, E> on(Expression<Boolean> restriction);
CollectionJoin<Z, E> on(Predicate... restrictions);
CollectionAttribute<? super Z, E> getModel();
}
/**
* Join to a java.util.Set
*/
public interface SetJoin<Z, E> extends PluralJoin<Z, Set<E>, E> {
SetJoin<Z, E> on(Expression<Boolean> restriction);
SetJoin<Z, E> on(Predicate... restrictions);
SetAttribute<? super Z, E> getModel();
}
/**
* Join to a java.util.List
*/
public interface ListJoin<Z, E> extends PluralJoin<Z, List<E>, E> {
ListJoin<Z, E> on(Expression<Boolean> restriction);
ListJoin<Z, E> on(Predicate... restrictions);
ListAttribute<? super Z, E> getModel();
Expression<Integer> index();
}
/**
* Join to a java.util.Map
*/
public interface MapJoin<Z, K, V> extends PluralJoin<Z, Map<K, V>, V> {
MapJoin<Z, K, V> on(Expression<Boolean> restriction);
MapJoin<Z, K, V> on(Predicate... restrictions);
MapAttribute<? super Z, K, V> getModel();
Path<K> key();
Path<V> value();
Expression<Map.Entry<K, V>> entry();
}
/**
* Join type enumeration
*/
public enum JoinType {
INNER,
LEFT,
RIGHT
}Usage Example:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> query = cb.createQuery(Order.class);
Root<Order> order = query.from(Order.class);
// Create joins
Join<Order, Customer> customer = order.join("customer", JoinType.INNER);
Join<Customer, Address> address = customer.join("address", JoinType.LEFT);
// Use ON condition
Join<Order, OrderItem> items = order.join("items");
items.on(cb.greaterThan(items.get("quantity"), 0));
query.where(cb.equal(address.get("city"), "New York"));Fetch joins for eagerly loading associations.
/**
* Parent interface for fetch operations
*/
public interface FetchParent<Z, X> {
Set<Fetch<X, ?>> getFetches();
<Y> Fetch<X, Y> fetch(SingularAttribute<? super X, Y> attribute);
<Y> Fetch<X, Y> fetch(SingularAttribute<? super X, Y> attribute, JoinType jt);
<Y> Fetch<X, Y> fetch(PluralAttribute<? super X, ?, Y> attribute);
<Y> Fetch<X, Y> fetch(PluralAttribute<? super X, ?, Y> attribute, JoinType jt);
<X, Y> Fetch<X, Y> fetch(String attributeName);
<X, Y> Fetch<X, Y> fetch(String attributeName, JoinType jt);
}
/**
* Represents a join-fetched association or attribute
*/
public interface Fetch<Z, X> extends FetchParent<Z, X> {
Attribute<? super Z, ?> getAttribute();
FetchParent<?, Z> getParent();
JoinType getJoinType();
}Usage Example:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> query = cb.createQuery(Order.class);
Root<Order> order = query.from(Order.class);
// Fetch associations eagerly
order.fetch("customer", JoinType.LEFT);
order.fetch("items", JoinType.LEFT);
List<Order> orders = em.createQuery(query).getResultList();
// Customer and items are eagerly loadedOrder expressions for sorting query results.
/**
* Defines an ordering over the query results
*/
public interface Order {
Order reverse();
boolean isAscending();
Expression<?> getExpression();
}Usage Example:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> user = query.from(User.class);
// Create ordering
Order nameOrder = cb.asc(user.get("name"));
Order ageOrder = cb.desc(user.get("age"));
query.orderBy(nameOrder, ageOrder);CriteriaBuilder defines several nested interfaces for building complex query expressions.
/**
* Enum used to specify how strings are trimmed
*/
public static enum Trimspec {
/** Trim from leading end */
LEADING,
/** Trim from trailing end */
TRAILING,
/** Trim from both ends */
BOTH
}
/**
* Interface used to build IN predicates
*/
public static interface In<T> extends Predicate {
/**
* Return the expression to be tested against the list of values
* @return expression
*/
Expression<T> getExpression();
/**
* Add to list of values to be tested against
* @param value value
* @return in predicate
*/
In<T> value(T value);
/**
* Add to list of values to be tested against
* @param value expression
* @return in predicate
*/
In<T> value(Expression<? extends T> value);
}
/**
* Interface used to build COALESCE expressions
*
* A coalesce expression is equivalent to a case expression that returns null
* if all its arguments evaluate to null, and the value of its first non-null
* argument otherwise
*/
public static interface Coalesce<T> extends Expression<T> {
/**
* Add an argument to the coalesce expression
* @param value value
* @return coalesce expression
*/
Coalesce<T> value(T value);
/**
* Add an argument to the coalesce expression
* @param value expression
* @return coalesce expression
*/
Coalesce<T> value(Expression<? extends T> value);
}
/**
* Interface used to build simple CASE expressions
*
* Case conditions are evaluated in the order in which they are specified
*/
public static interface SimpleCase<C, R> extends Expression<R> {
/**
* Return the expression to be tested against the conditions
* @return expression
*/
Expression<C> getExpression();
/**
* Add a when/then clause to the case expression
* @param condition "when" condition
* @param result "then" result value
* @return simple case expression
*/
SimpleCase<C, R> when(C condition, R result);
/**
* Add a when/then clause to the case expression
* @param condition "when" condition
* @param result "then" result expression
* @return simple case expression
*/
SimpleCase<C, R> when(C condition, Expression<? extends R> result);
/**
* Add a when/then clause to the case expression
* @param condition "when" condition
* @param result "then" result value
* @return simple case expression
*/
SimpleCase<C, R> when(Expression<? extends C> condition, R result);
/**
* Add a when/then clause to the case expression
* @param condition "when" condition
* @param result "then" result expression
* @return simple case expression
*/
SimpleCase<C, R> when(Expression<? extends C> condition, Expression<? extends R> result);
/**
* Add an "else" clause to the case expression
* @param result "else" result
* @return expression
*/
Expression<R> otherwise(R result);
/**
* Add an "else" clause to the case expression
* @param result "else" result expression
* @return expression
*/
Expression<R> otherwise(Expression<? extends R> result);
}
/**
* Interface used to build general CASE expressions
*
* Case conditions are evaluated in the order in which they are specified
*/
public static interface Case<R> extends Expression<R> {
/**
* Add a when/then clause to the case expression
* @param condition "when" condition
* @param result "then" result value
* @return general case expression
*/
Case<R> when(Expression<Boolean> condition, R result);
/**
* Add a when/then clause to the case expression
* @param condition "when" condition
* @param result "then" result expression
* @return general case expression
*/
Case<R> when(Expression<Boolean> condition, Expression<? extends R> result);
/**
* Add an "else" clause to the case expression
* @param result "else" result
* @return expression
*/
Expression<R> otherwise(R result);
/**
* Add an "else" clause to the case expression
* @param result "else" result expression
* @return expression
*/
Expression<R> otherwise(Expression<? extends R> result);
}Usage Examples:
IN Predicate:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> user = query.from(User.class);
// Build IN predicate
CriteriaBuilder.In<String> inPredicate = cb.in(user.get("status"));
inPredicate.value("ACTIVE").value("PENDING").value("APPROVED");
query.where(inPredicate);COALESCE Expression:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<String> query = cb.createQuery(String.class);
Root<User> user = query.from(User.class);
// Return nickname if not null, otherwise return username
CriteriaBuilder.Coalesce<String> coalesce = cb.coalesce();
coalesce.value(user.get("nickname")).value(user.get("username"));
query.select(coalesce);Simple CASE Expression:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<String> query = cb.createQuery(String.class);
Root<User> user = query.from(User.class);
// Map status codes to descriptions
CriteriaBuilder.SimpleCase<Integer, String> caseExpr =
cb.selectCase(user.get("statusCode"));
caseExpr.when(1, "Active")
.when(2, "Inactive")
.when(3, "Suspended")
.otherwise("Unknown");
query.select(caseExpr);General CASE Expression:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<String> query = cb.createQuery(String.class);
Root<User> user = query.from(User.class);
// Categorize users based on age
CriteriaBuilder.Case<String> caseExpr = cb.selectCase();
caseExpr.when(cb.lessThan(user.get("age"), 18), "Minor")
.when(cb.between(user.get("age"), 18, 65), "Adult")
.otherwise("Senior");
query.select(caseExpr);Install with Tessl CLI
npx tessl i tessl/maven-jakarta-persistence--jakarta-persistence-api