HHH-16899 add CriteriaDefinition utility class

This commit is contained in:
Gavin King 2023-07-05 18:18:35 +02:00
parent a440046556
commit 67ac383c26
3 changed files with 318 additions and 12 deletions

View File

@ -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.
* <p>
* For example:
* <pre>
* sessionFactory.inTransaction(session -> {
* List&lt;Book&gt; books
* = new CriteriaDefinition&lt;&gt;(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();
* });
* </pre>
*
*
* @param <R> the query result type
*/
@Incubating
public abstract class CriteriaDefinition<R>
extends HibernateCriteriaBuilderDelegate
implements JpaCriteriaQuery<R> {
private final Session session;
private final JpaCriteriaQuery<R> query;
public CriteriaDefinition(Session session, Class<R> resultType) {
super( session.getSessionFactory().getCriteriaBuilder() );
this.session = session;
query = createQuery( resultType );
define();
}
public SelectionQuery<R> createSelectionQuery() {
return session.createSelectionQuery(query);
}
public abstract void define();
@Override
public JpaCriteriaQuery<R> select(Selection<? extends R> selection) {
return query.select(selection);
}
@Override
public JpaCriteriaQuery<R> multiselect(Selection<?>... selections) {
return query.multiselect(selections);
}
@Override
public JpaCriteriaQuery<R> multiselect(List<Selection<?>> list) {
return query.multiselect(list);
}
@Override
public JpaCriteriaQuery<R> where(Expression<Boolean> restriction) {
return query.where(restriction);
}
@Override
public JpaCriteriaQuery<R> where(Predicate... restrictions) {
return query.where(restrictions);
}
@Override
public JpaCriteriaQuery<R> groupBy(Expression... grouping) {
return query.groupBy(grouping);
}
@Override
public JpaCriteriaQuery<R> groupBy(List<Expression<?>> grouping) {
return query.groupBy(grouping);
}
@Override
public JpaCriteriaQuery<R> having(Expression<Boolean> restriction) {
return query.having(restriction);
}
@Override
public JpaCriteriaQuery<R> having(Predicate... restrictions) {
return query.having(restrictions);
}
@Override
public JpaCriteriaQuery<R> orderBy(Order... o) {
return query.orderBy(o);
}
@Override
public JpaCriteriaQuery<R> orderBy(List<Order> o) {
return query.orderBy(o);
}
@Override
public JpaCriteriaQuery<R> distinct(boolean distinct) {
return query.distinct(distinct);
}
@Override
public List<Order> getOrderList() {
return query.getOrderList();
}
@Override
public Set<ParameterExpression<?>> getParameters() {
return query.getParameters();
}
@Override
public <X> JpaRoot<X> from(Class<X> entityClass) {
return query.from(entityClass);
}
@Override
public <X> JpaRoot<X> from(EntityType<X> entity) {
return query.from(entity);
}
@Override
public <U> JpaSubQuery<U> subquery(Class<U> type) {
return query.subquery(type);
}
@Override
public Set<Root<?>> getRoots() {
return query.getRoots();
}
@Override
public JpaSelection<R> getSelection() {
return query.getSelection();
}
@Override
public List<Expression<?>> getGroupList() {
return query.getGroupList();
}
@Override
public JpaPredicate getGroupRestriction() {
return query.getGroupRestriction();
}
@Override
public boolean isDistinct() {
return query.isDistinct();
}
@Override
public Class<R> getResultType() {
return query.getResultType();
}
@Override
public JpaPredicate getRestriction() {
return query.getRestriction();
}
@Override
public JpaExpression<Number> getOffset() {
return query.getOffset();
}
@Override
public JpaCriteriaQuery<R> offset(JpaExpression<? extends Number> offset) {
return query.offset(offset);
}
@Override
public JpaCriteriaQuery<R> offset(Number offset) {
return query.offset(offset);
}
@Override
public JpaExpression<Number> getFetch() {
return query.getFetch();
}
@Override
public JpaCriteriaQuery<R> fetch(JpaExpression<? extends Number> fetch) {
return query.fetch(fetch);
}
@Override
public JpaCriteriaQuery<R> fetch(JpaExpression<? extends Number> fetch, FetchClauseType fetchClauseType) {
return query.fetch(fetch, fetchClauseType);
}
@Override
public JpaCriteriaQuery<R> fetch(Number fetch) {
return query.fetch(fetch);
}
@Override
public JpaCriteriaQuery<R> fetch(Number fetch, FetchClauseType fetchClauseType) {
return query.fetch(fetch, fetchClauseType);
}
@Override
public FetchClauseType getFetchClauseType() {
return query.getFetchClauseType();
}
@Override
public List<Root<?>> getRootList() {
return query.getRootList();
}
@Override
public Collection<? extends JpaCteCriteria<?>> getCteCriterias() {
return query.getCteCriterias();
}
@Override
public <T> JpaCteCriteria<T> getCteCriteria(String cteName) {
return query.getCteCriteria(cteName);
}
@Override
public <T> JpaCteCriteria<T> with(AbstractQuery<T> criteria) {
return query.with(criteria);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionAll(AbstractQuery<T> baseCriteria, Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionAll(baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionDistinct(AbstractQuery<T> baseCriteria, Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionDistinct(baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> with(String name, AbstractQuery<T> criteria) {
return query.with(name, criteria);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionAll(
String name, AbstractQuery<T> baseCriteria,
Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionAll(name, baseCriteria, recursiveCriteriaProducer);
}
@Override
public <T> JpaCteCriteria<T> withRecursiveUnionDistinct(
String name, AbstractQuery<T> baseCriteria,
Function<JpaCteCriteria<T>, AbstractQuery<T>> recursiveCriteriaProducer) {
return query.withRecursiveUnionDistinct(name, baseCriteria, recursiveCriteriaProducer);
}
@Override
public JpaQueryStructure<R> getQuerySpec() {
return query.getQuerySpec();
}
@Override
public JpaQueryPart<R> getQueryPart() {
return query.getQueryPart();
}
@Override
public <X> JpaDerivedRoot<X> from(Subquery<X> subquery) {
return query.from(subquery);
}
@Override
public <X> JpaRoot<X> from(JpaCteCriteria<X> cte) {
return query.from(cte);
}
}

View File

@ -25,6 +25,9 @@
* which allows the creation of {@link org.hibernate.query.criteria.JpaCteCriteria
* common table expressions}.
* </ul>
* <p>
* 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

View File

@ -90,8 +90,8 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
return criteriaBuilder.wrap( expression );
}
@Override
public JpaPredicate wrap(Expression<Boolean>... expressions) {
@Override @SafeVarargs
public final JpaPredicate wrap(Expression<Boolean>... expressions) {
return criteriaBuilder.wrap( expressions );
}
@ -334,7 +334,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
}
@Override
public <Y> JpaCompoundSelection<Y> construct(Class<Y> resultClass, Selection<?>[] selections) {
public <Y> JpaCompoundSelection<Y> construct(Class<Y> resultClass, Selection<?>... selections) {
return criteriaBuilder.construct( resultClass, selections );
}
@ -344,7 +344,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
}
@Override
public JpaCompoundSelection<Tuple> tuple(Selection<?>[] selections) {
public JpaCompoundSelection<Tuple> tuple(Selection<?>... selections) {
return criteriaBuilder.tuple( selections );
}
@ -354,7 +354,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
}
@Override
public JpaCompoundSelection<Object[]> array(Selection<?>[] selections) {
public JpaCompoundSelection<Object[]> array(Selection<?>... selections) {
return criteriaBuilder.array( selections );
}
@ -364,7 +364,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
}
@Override
public <Y> JpaCompoundSelection<Y> array(Class<Y> resultClass, Selection<?>[] selections) {
public <Y> JpaCompoundSelection<Y> array(Class<Y> resultClass, Selection<?>... selections) {
return criteriaBuilder.array( resultClass, selections );
}
@ -553,8 +553,8 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
return criteriaBuilder.literal( value );
}
@Override
public <T> List<? extends JpaExpression<T>> literals(T[] values) {
@Override @SafeVarargs
public final <T> List<? extends JpaExpression<T>> literals(T... values) {
return criteriaBuilder.literals( values );
}
@ -1144,13 +1144,13 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
return criteriaBuilder.in( expression );
}
@Override
public <T> JpaInPredicate<T> in(Expression<? extends T> expression, Expression<? extends T>... values) {
@Override @SafeVarargs
public final <T> JpaInPredicate<T> in(Expression<? extends T> expression, Expression<? extends T>... values) {
return criteriaBuilder.in( expression, values );
}
@Override
public <T> JpaInPredicate<T> in(Expression<? extends T> expression, T... values) {
@Override @SafeVarargs
public final <T> JpaInPredicate<T> in(Expression<? extends T> expression, T... values) {
return criteriaBuilder.in( expression, values );
}