From 67ac383c26ebc85ba629bc0804d320367f5dc770 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Wed, 5 Jul 2023 18:18:35 +0200 Subject: [PATCH] HHH-16899 add CriteriaDefinition utility class --- .../query/criteria/CriteriaDefinition.java | 303 ++++++++++++++++++ .../query/criteria/package-info.java | 3 + .../spi/HibernateCriteriaBuilderDelegate.java | 24 +- 3 files changed, 318 insertions(+), 12 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/query/criteria/CriteriaDefinition.java diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/CriteriaDefinition.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/CriteriaDefinition.java new file mode 100644 index 0000000000..ee622c6af8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/CriteriaDefinition.java @@ -0,0 +1,303 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.query.criteria; + +import jakarta.persistence.criteria.*; +import jakarta.persistence.metamodel.EntityType; +import org.hibernate.Incubating; +import org.hibernate.Session; +import org.hibernate.query.SelectionQuery; +import org.hibernate.query.criteria.spi.HibernateCriteriaBuilderDelegate; +import org.hibernate.query.sqm.FetchClauseType; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +/** + * A utility class that makes it easier to build {@linkplain CriteriaQuery criteria queries}. + * From within an implementation of the {@link #define()} method, all operations of the + * {@link CriteriaBuilder} and {@link CriteriaQuery} may be called without the need for + * specifying the target object. + *

+ * For example: + *

+ * sessionFactory.inTransaction(session -> {
+ *     List<Book> books
+ *             = new CriteriaDefinition<>(session, Book.class) {
+ *                 public void define() {
+ *                     var book = from(Book.class);
+ *                     where(like(book.get(Book_.title), "%Hibernate%"));
+ *                     orderBy(desc(book.get(Book_.publicationDate)), asc(book.get(Book_.isbn)));
+ *                     book.fetch(Book_.authors);
+ *                 }
+ *             }
+ *             .createSelectionQuery()
+ *             .setMaxResults(10)
+ *             .getResultList();
+ * });
+ * 
+ * + * + * @param the query result type + */ +@Incubating +public abstract class CriteriaDefinition + extends HibernateCriteriaBuilderDelegate + implements JpaCriteriaQuery { + + private final Session session; + private final JpaCriteriaQuery query; + + public CriteriaDefinition(Session session, Class resultType) { + super( session.getSessionFactory().getCriteriaBuilder() ); + this.session = session; + query = createQuery( resultType ); + define(); + } + + public SelectionQuery createSelectionQuery() { + return session.createSelectionQuery(query); + } + + public abstract void define(); + + @Override + public JpaCriteriaQuery select(Selection selection) { + return query.select(selection); + } + + @Override + public JpaCriteriaQuery multiselect(Selection... selections) { + return query.multiselect(selections); + } + + @Override + public JpaCriteriaQuery multiselect(List> list) { + return query.multiselect(list); + } + + @Override + public JpaCriteriaQuery where(Expression restriction) { + return query.where(restriction); + } + + @Override + public JpaCriteriaQuery where(Predicate... restrictions) { + return query.where(restrictions); + } + + @Override + public JpaCriteriaQuery groupBy(Expression... grouping) { + return query.groupBy(grouping); + } + + @Override + public JpaCriteriaQuery groupBy(List> grouping) { + return query.groupBy(grouping); + } + + @Override + public JpaCriteriaQuery having(Expression restriction) { + return query.having(restriction); + } + + @Override + public JpaCriteriaQuery having(Predicate... restrictions) { + return query.having(restrictions); + } + + @Override + public JpaCriteriaQuery orderBy(Order... o) { + return query.orderBy(o); + } + + @Override + public JpaCriteriaQuery orderBy(List o) { + return query.orderBy(o); + } + + @Override + public JpaCriteriaQuery distinct(boolean distinct) { + return query.distinct(distinct); + } + + @Override + public List getOrderList() { + return query.getOrderList(); + } + + @Override + public Set> getParameters() { + return query.getParameters(); + } + + @Override + public JpaRoot from(Class entityClass) { + return query.from(entityClass); + } + + @Override + public JpaRoot from(EntityType entity) { + return query.from(entity); + } + + @Override + public JpaSubQuery subquery(Class type) { + return query.subquery(type); + } + + @Override + public Set> getRoots() { + return query.getRoots(); + } + + @Override + public JpaSelection getSelection() { + return query.getSelection(); + } + + @Override + public List> getGroupList() { + return query.getGroupList(); + } + + @Override + public JpaPredicate getGroupRestriction() { + return query.getGroupRestriction(); + } + + @Override + public boolean isDistinct() { + return query.isDistinct(); + } + + @Override + public Class getResultType() { + return query.getResultType(); + } + + @Override + public JpaPredicate getRestriction() { + return query.getRestriction(); + } + + @Override + public JpaExpression getOffset() { + return query.getOffset(); + } + + @Override + public JpaCriteriaQuery offset(JpaExpression offset) { + return query.offset(offset); + } + + @Override + public JpaCriteriaQuery offset(Number offset) { + return query.offset(offset); + } + + @Override + public JpaExpression getFetch() { + return query.getFetch(); + } + + @Override + public JpaCriteriaQuery fetch(JpaExpression fetch) { + return query.fetch(fetch); + } + + @Override + public JpaCriteriaQuery fetch(JpaExpression fetch, FetchClauseType fetchClauseType) { + return query.fetch(fetch, fetchClauseType); + } + + @Override + public JpaCriteriaQuery fetch(Number fetch) { + return query.fetch(fetch); + } + + @Override + public JpaCriteriaQuery fetch(Number fetch, FetchClauseType fetchClauseType) { + return query.fetch(fetch, fetchClauseType); + } + + @Override + public FetchClauseType getFetchClauseType() { + return query.getFetchClauseType(); + } + + @Override + public List> getRootList() { + return query.getRootList(); + } + + @Override + public Collection> getCteCriterias() { + return query.getCteCriterias(); + } + + @Override + public JpaCteCriteria getCteCriteria(String cteName) { + return query.getCteCriteria(cteName); + } + + @Override + public JpaCteCriteria with(AbstractQuery criteria) { + return query.with(criteria); + } + + @Override + public JpaCteCriteria withRecursiveUnionAll(AbstractQuery baseCriteria, Function, AbstractQuery> recursiveCriteriaProducer) { + return query.withRecursiveUnionAll(baseCriteria, recursiveCriteriaProducer); + } + + @Override + public JpaCteCriteria withRecursiveUnionDistinct(AbstractQuery baseCriteria, Function, AbstractQuery> recursiveCriteriaProducer) { + return query.withRecursiveUnionDistinct(baseCriteria, recursiveCriteriaProducer); + } + + @Override + public JpaCteCriteria with(String name, AbstractQuery criteria) { + return query.with(name, criteria); + } + + @Override + public JpaCteCriteria withRecursiveUnionAll( + String name, AbstractQuery baseCriteria, + Function, AbstractQuery> recursiveCriteriaProducer) { + return query.withRecursiveUnionAll(name, baseCriteria, recursiveCriteriaProducer); + } + + @Override + public JpaCteCriteria withRecursiveUnionDistinct( + String name, AbstractQuery baseCriteria, + Function, AbstractQuery> recursiveCriteriaProducer) { + return query.withRecursiveUnionDistinct(name, baseCriteria, recursiveCriteriaProducer); + } + + @Override + public JpaQueryStructure getQuerySpec() { + return query.getQuerySpec(); + } + + @Override + public JpaQueryPart getQueryPart() { + return query.getQueryPart(); + } + + @Override + public JpaDerivedRoot from(Subquery subquery) { + return query.from(subquery); + } + + @Override + public JpaRoot from(JpaCteCriteria cte) { + return query.from(cte); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/package-info.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/package-info.java index 5c64106d1b..5e570a5a7f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/package-info.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/package-info.java @@ -25,6 +25,9 @@ * which allows the creation of {@link org.hibernate.query.criteria.JpaCteCriteria * common table expressions}. * + *

+ * The class {@link org.hibernate.query.criteria.CriteriaDefinition} is a helpful + * utility that makes it easier to construct criteria queries. * * @see org.hibernate.query.criteria.HibernateCriteriaBuilder * @see org.hibernate.query.criteria.JpaCriteriaQuery diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java index 7652c67a46..57ad196c4c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java @@ -90,8 +90,8 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde return criteriaBuilder.wrap( expression ); } - @Override - public JpaPredicate wrap(Expression... expressions) { + @Override @SafeVarargs + public final JpaPredicate wrap(Expression... expressions) { return criteriaBuilder.wrap( expressions ); } @@ -334,7 +334,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde } @Override - public JpaCompoundSelection construct(Class resultClass, Selection[] selections) { + public JpaCompoundSelection construct(Class resultClass, Selection... selections) { return criteriaBuilder.construct( resultClass, selections ); } @@ -344,7 +344,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde } @Override - public JpaCompoundSelection tuple(Selection[] selections) { + public JpaCompoundSelection tuple(Selection... selections) { return criteriaBuilder.tuple( selections ); } @@ -354,7 +354,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde } @Override - public JpaCompoundSelection array(Selection[] selections) { + public JpaCompoundSelection array(Selection... selections) { return criteriaBuilder.array( selections ); } @@ -364,7 +364,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde } @Override - public JpaCompoundSelection array(Class resultClass, Selection[] selections) { + public JpaCompoundSelection array(Class resultClass, Selection... selections) { return criteriaBuilder.array( resultClass, selections ); } @@ -553,8 +553,8 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde return criteriaBuilder.literal( value ); } - @Override - public List> literals(T[] values) { + @Override @SafeVarargs + public final List> literals(T... values) { return criteriaBuilder.literals( values ); } @@ -1144,13 +1144,13 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde return criteriaBuilder.in( expression ); } - @Override - public JpaInPredicate in(Expression expression, Expression... values) { + @Override @SafeVarargs + public final JpaInPredicate in(Expression expression, Expression... values) { return criteriaBuilder.in( expression, values ); } - @Override - public JpaInPredicate in(Expression expression, T... values) { + @Override @SafeVarargs + public final JpaInPredicate in(Expression expression, T... values) { return criteriaBuilder.in( expression, values ); }