HHH-18517 allow composition of CriteriaDefinitions
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
4fd9a4f0df
commit
d306aadb9d
|
@ -18,6 +18,8 @@ import org.hibernate.query.QueryProducer;
|
|||
import org.hibernate.query.SelectionQuery;
|
||||
import org.hibernate.query.criteria.spi.HibernateCriteriaBuilderDelegate;
|
||||
import org.hibernate.query.sqm.FetchClauseType;
|
||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -85,6 +87,28 @@ import java.util.function.Function;
|
|||
* ...
|
||||
* });
|
||||
* </pre>
|
||||
* A {@code CriteriaDefinition} may be used to modify another {@code CriteriaDefinition}:
|
||||
* <pre>
|
||||
* var bookFilter
|
||||
* = new CriteriaDefinition<>(sessionFactory, Book.class) {{
|
||||
* where(like(from(Book.class).get(Book_.title), "%Hibernate%"));
|
||||
* }};
|
||||
* long count
|
||||
* = new CriteriaDefinition<>(bookFilter, Long.class) {{
|
||||
* select(count());
|
||||
* }}
|
||||
* .createSelectionQuery(session)
|
||||
* .getSingleResult();
|
||||
* var books =
|
||||
* = new CriteriaDefinition<>(bookFilter) {{
|
||||
* var book = (Root<Book>) getRootList().get(0);
|
||||
* book.fetch(Book_.authors);
|
||||
* orderBy(desc(book.get(Book_.publicationDate)), asc(book.get(Book_.isbn)));
|
||||
* }}
|
||||
* .createSelectionQuery(session)
|
||||
* .setMaxResults(10)
|
||||
* .getResultList();
|
||||
* </pre>
|
||||
*
|
||||
* @param <R> the query result type
|
||||
*
|
||||
|
@ -99,6 +123,37 @@ public abstract class CriteriaDefinition<R>
|
|||
|
||||
private final JpaCriteriaQuery<R> query;
|
||||
|
||||
/**
|
||||
* Construct a new {@code CriteriaDefinition} based on the given
|
||||
* {@code CriteriaDefinition}, with the same query return type.
|
||||
*
|
||||
* @param template the original query
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
public CriteriaDefinition(CriteriaDefinition<R> template) {
|
||||
super( template.getCriteriaBuilder() );
|
||||
query = ((SqmSelectStatement<R>) template.query)
|
||||
.copy( SqmCopyContext.simpleContext() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code CriteriaDefinition} based on the given
|
||||
* {@code CriteriaDefinition}. This overload permits changing the
|
||||
* query return type. It is expected that {@link #select} be called
|
||||
* to rewrite the selection list.
|
||||
*
|
||||
* @param template the original query
|
||||
* @param resultType the new return type
|
||||
*
|
||||
* @since 7.0
|
||||
*/
|
||||
public CriteriaDefinition(CriteriaDefinition<?> template, Class<R> resultType) {
|
||||
super( template.getCriteriaBuilder() );
|
||||
query = ((SqmSelectStatement<?>) template.query)
|
||||
.createCopy( SqmCopyContext.simpleContext(), resultType );
|
||||
}
|
||||
|
||||
public CriteriaDefinition(SessionFactory factory, Class<R> resultType) {
|
||||
super( factory.getCriteriaBuilder() );
|
||||
query = createQuery( resultType );
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
import org.hibernate.query.criteria.JpaCriteriaQuery;
|
||||
import org.hibernate.query.criteria.JpaExpression;
|
||||
import org.hibernate.query.criteria.JpaSelection;
|
||||
|
@ -26,8 +27,6 @@ import org.hibernate.query.sqm.tree.SqmStatement;
|
|||
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
||||
import org.hibernate.query.sqm.tree.expression.ValueBindJpaCriteriaParameter;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
||||
import org.hibernate.query.sqm.tree.expression.ValueBindJpaCriteriaParameter;
|
||||
import org.hibernate.query.sqm.tree.from.SqmFromClause;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||
|
@ -127,7 +126,8 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
|
|||
return createCopy( context, getResultType() );
|
||||
}
|
||||
|
||||
private <X> SqmSelectStatement<X> createCopy(SqmCopyContext context, Class<X> resultType) {
|
||||
@Internal
|
||||
public <X> SqmSelectStatement<X> createCopy(SqmCopyContext context, Class<X> resultType) {
|
||||
final Set<SqmParameter<?>> parameters;
|
||||
if ( this.parameters == null ) {
|
||||
parameters = null;
|
||||
|
|
|
@ -54,6 +54,11 @@ public class CriteriaDefinitionTest {
|
|||
orderBy(asc(message.get("id")));
|
||||
}};
|
||||
|
||||
var query5 = new CriteriaDefinition<>(query4, Long.class) {{
|
||||
select(count());
|
||||
orderBy();
|
||||
}};
|
||||
|
||||
scope.inSession(session -> {
|
||||
var idAndText = session.createSelectionQuery(query1).getSingleResult();
|
||||
assertNotNull(idAndText);
|
||||
|
@ -72,6 +77,9 @@ public class CriteriaDefinitionTest {
|
|||
assertNotNull(msg);
|
||||
assertEquals(1L,msg.id);
|
||||
assertEquals("hello",msg.text);
|
||||
|
||||
long count = session.createSelectionQuery(query5).getSingleResult();
|
||||
assertEquals(1L,count);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue