HHH-17779 support for key-based pagination
This commit is contained in:
parent
2f4a6ebcaf
commit
4fbcfbdaba
|
@ -13,7 +13,6 @@ import org.hibernate.Incubating;
|
|||
import org.hibernate.graph.GraphSemantic;
|
||||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.util.NullnessUtil;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.Set;
|
|||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.ConnectionAcquisitionMode;
|
||||
import org.hibernate.FetchNotFoundException;
|
||||
import org.hibernate.Filter;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Interceptor;
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.hibernate.loader.ast.spi.Loadable;
|
|||
import org.hibernate.loader.ast.spi.Loader;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
|
||||
/**
|
||||
* Support for pagination based on a unique key of the result
|
||||
* set instead of the {@link Page#getFirstResult() offset}.
|
||||
*
|
||||
* @since 6.5
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class KeyedPage<R> {
|
||||
private final List<Order<? super R>> keyDefinition;
|
||||
private final Page page;
|
||||
private final List<Comparable<?>> key;
|
||||
|
||||
KeyedPage(List<Order<? super R>> keyDefinition, Page page) {
|
||||
this( keyDefinition, page, null );
|
||||
}
|
||||
|
||||
public KeyedPage(List<Order<? super R>> keyDefinition, Page page, List<Comparable<?>> key) {
|
||||
this.page = page;
|
||||
this.keyDefinition = unmodifiableList(keyDefinition);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public List<Order<? super R>> getKeyDefinition() {
|
||||
return keyDefinition;
|
||||
}
|
||||
|
||||
public Page getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Null key indicates that the {@linkplain Page#getNumber() page number}
|
||||
* should be used. This is useful to obtain an initial page of results.
|
||||
*/
|
||||
public List<Comparable<?>> getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@ package org.hibernate.query;
|
|||
|
||||
import org.hibernate.Incubating;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Identifies a page of query results by {@linkplain #size page size}
|
||||
* and {@linkplain #number page number}.
|
||||
|
@ -50,7 +52,7 @@ public class Page {
|
|||
return size*number;
|
||||
}
|
||||
|
||||
private Page(int size, int number) {
|
||||
Page(int size, int number) {
|
||||
if ( size <= 0 ) {
|
||||
throw new IllegalArgumentException("page size must be strictly positive");
|
||||
}
|
||||
|
@ -83,4 +85,8 @@ public class Page {
|
|||
public Page first() {
|
||||
return first( size );
|
||||
}
|
||||
|
||||
public <R> KeyedPage<R> keyedBy(List<Order<? super R>> keyDefinition) {
|
||||
return new KeyedPage<>( keyDefinition, this );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -903,6 +903,11 @@ public interface Query<R> extends SelectionQuery<R>, MutationQuery, TypedQuery<R
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default SelectionQuery<R> setPage(KeyedPage<R> page) {
|
||||
throw new UnsupportedOperationException("keyed paging not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
Query<R> setHint(String hintName, Object value);
|
||||
|
||||
|
|
|
@ -395,6 +395,16 @@ public interface SelectionQuery<R> extends CommonQueryContract {
|
|||
@Incubating
|
||||
SelectionQuery<R> setPage(Page page);
|
||||
|
||||
/**
|
||||
* Set the {@linkplain KeyedPage keyed page} of results to return.
|
||||
*
|
||||
* @see KeyedPage
|
||||
*
|
||||
* @since 6.5
|
||||
*/
|
||||
@Incubating
|
||||
SelectionQuery<R> setPage(KeyedPage<R> page);
|
||||
|
||||
/**
|
||||
* Obtain the {@link CacheMode} in effect for this query. By default,
|
||||
* the query inherits the {@link CacheMode} of the session from which
|
||||
|
|
|
@ -6,22 +6,40 @@
|
|||
*/
|
||||
package org.hibernate.query.sqm.internal;
|
||||
|
||||
import jakarta.persistence.criteria.Expression;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.query.IllegalQueryOperationException;
|
||||
import org.hibernate.query.IllegalSelectQueryException;
|
||||
import org.hibernate.query.KeyedPage;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.Page;
|
||||
import org.hibernate.query.QueryLogging;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
import org.hibernate.query.criteria.JpaSelection;
|
||||
import org.hibernate.query.hql.internal.QuerySplitter;
|
||||
import org.hibernate.query.spi.AbstractSelectionQuery;
|
||||
import org.hibernate.query.spi.MutableQueryOptions;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.spi.SelectQueryPlan;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.query.sqm.tree.from.SqmFrom;
|
||||
import org.hibernate.query.sqm.tree.from.SqmRoot;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
|
||||
import org.hibernate.query.sqm.tree.select.SqmQuerySpec;
|
||||
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
|
||||
import org.hibernate.sql.results.internal.TupleMetadata;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.hibernate.cfg.QuerySettings.FAIL_ON_PAGINATION_OVER_COLLECTION_FETCH;
|
||||
import static org.hibernate.query.sqm.internal.SqmUtil.sortSpecification;
|
||||
import static org.hibernate.query.sqm.tree.SqmCopyContext.noParamCopyContext;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
|
@ -73,8 +91,115 @@ abstract class AbstractSqmSelectionQuery<R> extends AbstractSelectionQuery<R> {
|
|||
}
|
||||
|
||||
public abstract SqmStatement<R> getSqmStatement();
|
||||
protected abstract void setSqmStatement(SqmSelectStatement<R> statement);
|
||||
public abstract DomainParameterXref getDomainParameterXref();
|
||||
public abstract TupleMetadata getTupleMetadata();
|
||||
|
||||
private SqmSelectStatement<R> getSqmSelectStatement() {
|
||||
final SqmStatement<R> sqmStatement = getSqmStatement();
|
||||
if ( sqmStatement instanceof SqmSelectStatement ) {
|
||||
return (SqmSelectStatement<R>) sqmStatement;
|
||||
}
|
||||
else {
|
||||
throw new IllegalSelectQueryException( "Not a select query" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setOrder(List<Order<? super R>> orderList) {
|
||||
SqmSelectStatement<R> sqm = getSqmSelectStatement();
|
||||
sqm = sqm.copy( noParamCopyContext() );
|
||||
final SqmSelectStatement<R> select = sqm;
|
||||
sqm.orderBy( orderList.stream().map( order -> sortSpecification( select, order ) )
|
||||
.collect( toList() ) );
|
||||
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
|
||||
// simply cache the new SQM as if it were a criteria query, and remove this:
|
||||
getQueryOptions().setQueryPlanCachingEnabled( false );
|
||||
setSqmStatement( sqm );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setOrder(Order<? super R> order) {
|
||||
SqmSelectStatement<R> sqm = getSqmSelectStatement();
|
||||
sqm = sqm.copy( noParamCopyContext() );
|
||||
sqm.orderBy( sortSpecification( sqm, order ) );
|
||||
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
|
||||
// simply cache the new SQM as if it were a criteria query, and remove this:
|
||||
getQueryOptions().setQueryPlanCachingEnabled( false );
|
||||
setSqmStatement( sqm );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setPage(Page page) {
|
||||
setMaxResults( page.getMaxResults() );
|
||||
setFirstResult( page.getFirstResult() );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setPage(KeyedPage<R> page) {
|
||||
setOrder( page.getKeyDefinition() );
|
||||
setMaxResults( page.getPage().getMaxResults() );
|
||||
if ( page.getKey() == null ) {
|
||||
setFirstResult( page.getPage().getFirstResult() );
|
||||
}
|
||||
else {
|
||||
addRestrictions( page.getKeyDefinition(), page.getKey() );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addRestrictions(List<Order<? super R>> keyDefinition, List<Comparable<?>> keyValues) {
|
||||
SqmSelectStatement<R> sqm = getSqmSelectStatement();
|
||||
sqm = sqm.copy( noParamCopyContext() );
|
||||
final SqmQuerySpec<R> querySpec = sqm.getQuerySpec();
|
||||
final SqmWhereClause whereClause = querySpec.getWhereClause();
|
||||
final List<? extends JpaSelection<?>> items = querySpec.getSelectClause().getSelectionItems();
|
||||
if ( items.size() == 1 ) {
|
||||
final JpaSelection<?> selected = items.get(0);
|
||||
for ( int i = 0; i < keyDefinition.size(); i++ ) {
|
||||
// ordering by an attribute of the returned entity
|
||||
if ( selected instanceof SqmRoot ) {
|
||||
whereClause.applyPredicate( keyPredicate(
|
||||
(SqmFrom<?,?>) selected,
|
||||
keyDefinition.get(i),
|
||||
(Comparable) keyValues.get(i))
|
||||
);
|
||||
}
|
||||
else {
|
||||
throw new IllegalQueryOperationException("Select item was not an entity type");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalQueryOperationException("Query has multiple items in the select list");
|
||||
}
|
||||
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
|
||||
// simply cache the new SQM as if it were a criteria query, and remove this:
|
||||
getQueryOptions().setQueryPlanCachingEnabled( false );
|
||||
setSqmStatement( sqm );
|
||||
}
|
||||
|
||||
private <C extends Comparable<? super C>> SqmPredicate keyPredicate(
|
||||
SqmFrom<?, ?> selected, Order<? super R> key, C keyValue) {
|
||||
if ( !key.getEntityClass().isAssignableFrom( selected.getJavaType() ) ) {
|
||||
throw new IllegalQueryOperationException("Select item was of wrong entity type");
|
||||
}
|
||||
final Expression<? extends C> path = selected.get( key.getAttributeName() );
|
||||
final NodeBuilder builder = getSqmStatement().nodeBuilder();
|
||||
switch ( key.getDirection() ) {
|
||||
case ASCENDING:
|
||||
return builder.greaterThan( path, keyValue);
|
||||
case DESCENDING:
|
||||
return builder.lessThan( path, keyValue);
|
||||
default:
|
||||
throw new AssertionFailure("Unrecognized key direction");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Class<R> getExpectedResultType();
|
||||
|
||||
protected SelectQueryPlan<R> buildSelectQueryPlan() {
|
||||
|
|
|
@ -47,9 +47,10 @@ import org.hibernate.persister.entity.AbstractEntityPersister;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.IllegalQueryOperationException;
|
||||
import org.hibernate.query.IllegalSelectQueryException;
|
||||
import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
|
||||
import org.hibernate.query.KeyedPage;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.Page;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.query.QueryParameter;
|
||||
import org.hibernate.query.ResultListTransformer;
|
||||
|
@ -109,7 +110,6 @@ import jakarta.persistence.PersistenceException;
|
|||
import jakarta.persistence.TemporalType;
|
||||
import org.hibernate.sql.results.spi.SingleResultConsumer;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHE_MODE;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHE_REGION;
|
||||
|
@ -126,10 +126,8 @@ import static org.hibernate.query.sqm.internal.AppliedGraphs.containsCollectionF
|
|||
import static org.hibernate.query.sqm.internal.SqmInterpretationsKey.createInterpretationsKey;
|
||||
import static org.hibernate.query.sqm.internal.SqmInterpretationsKey.generateNonSelectKey;
|
||||
import static org.hibernate.query.sqm.internal.SqmUtil.isSelect;
|
||||
import static org.hibernate.query.sqm.internal.SqmUtil.sortSpecification;
|
||||
import static org.hibernate.query.sqm.internal.SqmUtil.verifyIsNonSelectStatement;
|
||||
import static org.hibernate.query.sqm.internal.TypecheckUtil.assertAssignable;
|
||||
import static org.hibernate.query.sqm.tree.SqmCopyContext.noParamCopyContext;
|
||||
|
||||
/**
|
||||
* {@link Query} implementation based on an SQM
|
||||
|
@ -426,6 +424,11 @@ public class QuerySqmImpl<R>
|
|||
return sqm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSqmStatement(SqmSelectStatement<R> sqm) {
|
||||
this.sqm = sqm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainParameterXref getDomainParameterXref() {
|
||||
return domainParameterXref;
|
||||
|
@ -903,36 +906,27 @@ public class QuerySqmImpl<R>
|
|||
}
|
||||
|
||||
@Override
|
||||
public Query<R> setOrder(List<Order<? super R>> orderList) {
|
||||
if ( sqm instanceof SqmSelectStatement ) {
|
||||
sqm = sqm.copy( noParamCopyContext() );
|
||||
final SqmSelectStatement<R> select = (SqmSelectStatement<R>) sqm;
|
||||
select.orderBy( orderList.stream().map( order -> sortSpecification( select, order ) )
|
||||
.collect( toList() ) );
|
||||
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
|
||||
// simply cache the new SQM as if it were a criteria query, and remove this:
|
||||
getQueryOptions().setQueryPlanCachingEnabled( false );
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
throw new IllegalSelectQueryException( "Not a select query" );
|
||||
}
|
||||
public Query<R> setOrder(Order<? super R> order) {
|
||||
super.setOrder(order);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<R> setOrder(Order<? super R> order) {
|
||||
if ( sqm instanceof SqmSelectStatement ) {
|
||||
sqm = sqm.copy( noParamCopyContext() );
|
||||
SqmSelectStatement<R> select = (SqmSelectStatement<R>) sqm;
|
||||
select.orderBy( sortSpecification( select, order ) );
|
||||
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
|
||||
// simply cache the new SQM as if it were a criteria query, and remove this:
|
||||
getQueryOptions().setQueryPlanCachingEnabled( false );
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
throw new IllegalSelectQueryException( "Not a select query" );
|
||||
}
|
||||
public Query<R> setOrder(List<Order<? super R>> orders) {
|
||||
super.setOrder(orders);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<R> setPage(Page page) {
|
||||
super.setPage(page);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<R> setPage(KeyedPage<R> page) {
|
||||
super.setPage(page);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.internal.util.collections.IdentitySet;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.Page;
|
||||
import org.hibernate.query.QueryParameter;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
|
@ -63,7 +62,6 @@ import org.hibernate.sql.results.internal.TupleMetadata;
|
|||
import org.hibernate.sql.results.spi.ResultsConsumer;
|
||||
import org.hibernate.sql.results.spi.SingleResultConsumer;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHE_MODE;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CACHE_REGION;
|
||||
|
@ -77,7 +75,6 @@ import static org.hibernate.jpa.SpecHints.HINT_SPEC_CACHE_STORE_MODE;
|
|||
import static org.hibernate.query.spi.SqlOmittingQueryOptions.omitSqlQueryOptions;
|
||||
import static org.hibernate.query.sqm.internal.SqmInterpretationsKey.createInterpretationsKey;
|
||||
import static org.hibernate.query.sqm.internal.SqmUtil.isSelectionAssignableToResultType;
|
||||
import static org.hibernate.query.sqm.internal.SqmUtil.sortSpecification;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -245,6 +242,11 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
|
|||
return sqm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setSqmStatement(SqmSelectStatement<R> sqm) {
|
||||
this.sqm = sqm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainParameterXref getDomainParameterXref() {
|
||||
return domainParameterXref;
|
||||
|
@ -275,34 +277,6 @@ public class SqmSelectionQueryImpl<R> extends AbstractSqmSelectionQuery<R>
|
|||
// return this;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setPage(Page page) {
|
||||
setMaxResults( page.getMaxResults() );
|
||||
setFirstResult( page.getFirstResult() );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setOrder(List<Order<? super R>> orderList) {
|
||||
sqm = sqm.copy( SqmCopyContext.noParamCopyContext() );
|
||||
sqm.orderBy( orderList.stream().map( order -> sortSpecification( sqm, order ) )
|
||||
.collect( toList() ) );
|
||||
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
|
||||
// simply cache the new SQM as if it were a criteria query, and remove this:
|
||||
getQueryOptions().setQueryPlanCachingEnabled( false );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setOrder(Order<? super R> order) {
|
||||
sqm = sqm.copy( SqmCopyContext.noParamCopyContext() );
|
||||
sqm.orderBy( sortSpecification( sqm, order ) );
|
||||
// TODO: when the QueryInterpretationCache can handle caching criteria queries,
|
||||
// simply cache the new SQM as if it were a criteria query, and remove this:
|
||||
getQueryOptions().setQueryPlanCachingEnabled( false );
|
||||
return this;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// execution
|
||||
|
||||
|
|
|
@ -568,10 +568,12 @@ public class SqmUtil {
|
|||
final List<SqmSelectableNode<?>> items = sqm.getQuerySpec().getSelectClause().getSelectionItems();
|
||||
int element = order.getElement();
|
||||
if ( element < 1) {
|
||||
throw new IllegalQueryOperationException("Cannot order by element " + element + " (the first select item is element 1)");
|
||||
throw new IllegalQueryOperationException("Cannot order by element " + element
|
||||
+ " (the first select item is element 1)");
|
||||
}
|
||||
if ( element > items.size() ) {
|
||||
throw new IllegalQueryOperationException("Cannot order by element " + element + " (there are only " + items.size() + " select items)");
|
||||
throw new IllegalQueryOperationException("Cannot order by element " + element
|
||||
+ " (there are only " + items.size() + " select items)");
|
||||
}
|
||||
final SqmSelectableNode<?> selected = items.get( element-1 );
|
||||
|
||||
|
|
|
@ -25,10 +25,12 @@ import org.hibernate.ScrollMode;
|
|||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.graph.GraphSemantic;
|
||||
import org.hibernate.query.BindableType;
|
||||
import org.hibernate.query.KeyedPage;
|
||||
import org.hibernate.query.Order;
|
||||
import org.hibernate.query.Page;
|
||||
import org.hibernate.query.ParameterMetadata;
|
||||
import org.hibernate.query.QueryParameter;
|
||||
import org.hibernate.query.SelectionQuery;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||
import org.hibernate.sql.results.spi.ResultsConsumer;
|
||||
|
@ -196,6 +198,12 @@ public abstract class DelegatingSqmSelectionQueryImplementor<R> implements SqmSe
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionQuery<R> setPage(KeyedPage<R> page) {
|
||||
getDelegate().setPage( page );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CacheMode getCacheMode() {
|
||||
return getDelegate().getCacheMode();
|
||||
|
|
Loading…
Reference in New Issue