Skip to content

Commit 7c79f1a

Browse files
committed
HHH-19364 add support for QuerySpecification with criteria queries
1 parent 95372a0 commit 7c79f1a

File tree

8 files changed

+153
-0
lines changed

8 files changed

+153
-0
lines changed

hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,26 @@ public <T> SelectionSpecification<T> createSelectionSpecification(Class<T> rootE
667667
return delegate.createSelectionSpecification( rootEntityType );
668668
}
669669

670+
@Override
671+
public <T> SelectionSpecification<T> createSelectionSpecification(CriteriaQuery<T> criteria) {
672+
return delegate.createSelectionSpecification( criteria );
673+
}
674+
670675
@Override
671676
public <T> MutationSpecification<T> createMutationSpecification(String hql, Class<T> mutationTarget) {
672677
return delegate.createMutationSpecification( hql, mutationTarget );
673678
}
674679

680+
@Override
681+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaUpdate<T> criteriaUpdate) {
682+
return delegate.createMutationSpecification( criteriaUpdate );
683+
}
684+
685+
@Override
686+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaDelete<T> criteriaDelete) {
687+
return delegate.createMutationSpecification( criteriaDelete );
688+
}
689+
675690
@Override
676691
public MutationQuery createNativeMutationQuery(String sqlString) {
677692
return delegate.createNativeMutationQuery( sqlString );

hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,11 +760,26 @@ public <T> SelectionSpecification<T> createSelectionSpecification(Class<T> rootE
760760
return this.lazySession.get().createSelectionSpecification( rootEntityType );
761761
}
762762

763+
@Override
764+
public <T> SelectionSpecification<T> createSelectionSpecification(CriteriaQuery<T> criteria) {
765+
return this.lazySession.get().createSelectionSpecification( criteria );
766+
}
767+
763768
@Override
764769
public <T> MutationSpecification<T> createMutationSpecification(String hql, Class<T> mutationTarget) {
765770
return this.lazySession.get().createMutationSpecification( hql, mutationTarget );
766771
}
767772

773+
@Override
774+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaUpdate<T> criteriaUpdate) {
775+
return this.lazySession.get().createMutationSpecification( criteriaUpdate );
776+
}
777+
778+
@Override
779+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaDelete<T> criteriaDelete) {
780+
return this.lazySession.get().createMutationSpecification( criteriaDelete );
781+
}
782+
768783
@SuppressWarnings("rawtypes")
769784
@Override
770785
@Deprecated

hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionDelegatorBaseImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,26 @@ public <T> SelectionSpecification<T> createSelectionSpecification(Class<T> rootE
239239
return delegate.createSelectionSpecification( rootEntityType );
240240
}
241241

242+
@Override
243+
public <T> SelectionSpecification<T> createSelectionSpecification(CriteriaQuery<T> criteria) {
244+
return delegate.createSelectionSpecification( criteria );
245+
}
246+
242247
@Override
243248
public <T> MutationSpecification<T> createMutationSpecification(String hql, Class<T> mutationTarget) {
244249
return delegate.createMutationSpecification( hql, mutationTarget );
245250
}
246251

252+
@Override
253+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaUpdate<T> criteriaUpdate) {
254+
return delegate.createMutationSpecification( criteriaUpdate );
255+
}
256+
257+
@Override
258+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaDelete<T> criteriaDelete) {
259+
return delegate.createMutationSpecification( criteriaDelete );
260+
}
261+
247262
@Override
248263
public MutationQuery createNativeMutationQuery(String sqlString) {
249264
return delegate.createNativeMutationQuery( sqlString );

hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,11 +1270,26 @@ public <T> SelectionSpecification<T> createSelectionSpecification(Class<T> rootE
12701270
return new SelectionSpecificationImpl<>( rootEntityType, this );
12711271
}
12721272

1273+
@Override
1274+
public <T> SelectionSpecification<T> createSelectionSpecification(CriteriaQuery<T> criteria) {
1275+
return new SelectionSpecificationImpl<>( criteria, this );
1276+
}
1277+
12731278
@Override
12741279
public <T> MutationSpecification<T> createMutationSpecification(String hql, Class<T> mutationTarget) {
12751280
return new MutationSpecificationImpl<>( hql, mutationTarget, this );
12761281
}
12771282

1283+
@Override
1284+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaDelete<T> criteriaDelete) {
1285+
return new MutationSpecificationImpl<>( criteriaDelete, this );
1286+
}
1287+
1288+
@Override
1289+
public <T> MutationSpecification<T> createMutationSpecification(CriteriaUpdate<T> criteriaUpdate) {
1290+
return new MutationSpecificationImpl<>( criteriaUpdate, this );
1291+
}
1292+
12781293
protected <T> NativeQueryImplementor<T> createNativeQueryImplementor(String queryName, NamedNativeQueryMemento<T> memento) {
12791294
final NativeQueryImplementor<T> query = memento.toQuery( this );
12801295
final Boolean isUnequivocallySelect = query.isSelectQuery();

hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,21 @@ <T> SelectionSpecification<T> createSelectionSpecification(String hql, Class<T>
538538
@Incubating
539539
<T> SelectionSpecification<T> createSelectionSpecification(Class<T> rootEntityType);
540540

541+
/**
542+
* Returns a specification reference which can be used to programmatically,
543+
* iteratively build a {@linkplain SelectionQuery} for the given criteria query,
544+
* allowing the addition of {@linkplain SelectionSpecification#addOrdering sorting}
545+
* and {@linkplain SelectionSpecification#addRestriction restrictions}.
546+
*
547+
* @param criteria The criteria query
548+
*
549+
* @param <T> The entity type which is the root of the query.
550+
*
551+
* @since 7.0
552+
*/
553+
@Incubating
554+
<T> SelectionSpecification<T> createSelectionSpecification(CriteriaQuery<T> criteria);
555+
541556
/**
542557
* Returns a specification reference which can be used to programmatically,
543558
* iteratively build a {@linkplain MutationQuery} based on a base HQL statement,
@@ -558,6 +573,34 @@ <T> SelectionSpecification<T> createSelectionSpecification(String hql, Class<T>
558573
<T> MutationSpecification<T> createMutationSpecification(String hql, Class<T> mutationTarget)
559574
throws IllegalMutationQueryException;
560575

576+
/**
577+
* Returns a specification reference which can be used to programmatically,
578+
* iteratively build a {@linkplain MutationQuery} based on the given criteria update,
579+
* allowing the addition of {@linkplain MutationSpecification#addRestriction restrictions}.
580+
*
581+
* @param criteriaUpdate The criteria update query
582+
*
583+
* @param <T> The root entity type for the mutation (the "target").
584+
*
585+
* @since 7.0
586+
*/
587+
@Incubating
588+
<T> MutationSpecification<T> createMutationSpecification(CriteriaUpdate<T> criteriaUpdate);
589+
590+
/**
591+
* Returns a specification reference which can be used to programmatically,
592+
* iteratively build a {@linkplain MutationQuery} based on the given criteria delete,
593+
* allowing the addition of {@linkplain MutationSpecification#addRestriction restrictions}.
594+
*
595+
* @param criteriaDelete The criteria delete query
596+
*
597+
* @param <T> The root entity type for the mutation (the "target").
598+
*
599+
* @since 7.0
600+
*/
601+
@Incubating
602+
<T> MutationSpecification<T> createMutationSpecification(CriteriaDelete<T> criteriaDelete);
603+
561604
/**
562605
* Create a {@link Query} instance for the named query.
563606
*

hibernate-core/src/main/java/org/hibernate/query/programmatic/internal/MutationSpecificationImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package org.hibernate.query.programmatic.internal;
66

77
import jakarta.persistence.criteria.CommonAbstractCriteria;
8+
import jakarta.persistence.criteria.CriteriaDelete;
9+
import jakarta.persistence.criteria.CriteriaUpdate;
810
import jakarta.persistence.criteria.Root;
911
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1012
import org.hibernate.query.programmatic.MutationSpecification;
@@ -17,8 +19,10 @@
1719
import org.hibernate.query.sqm.internal.QuerySqmImpl;
1820
import org.hibernate.query.sqm.internal.SqmUtil;
1921
import org.hibernate.query.sqm.tree.SqmDeleteOrUpdateStatement;
22+
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
2023
import org.hibernate.query.sqm.tree.from.SqmRoot;
2124
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
25+
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
2226

2327
import java.util.Locale;
2428

@@ -44,6 +48,22 @@ public MutationSpecificationImpl(
4448
this.mutationTargetRoot = resolveSqmRoot( this.sqmStatement, mutationTarget );
4549
}
4650

51+
public MutationSpecificationImpl(
52+
CriteriaUpdate<T> criteriaQuery,
53+
SharedSessionContractImplementor session) {
54+
this.session = session;
55+
this.sqmStatement = (SqmUpdateStatement<T>) criteriaQuery;
56+
this.mutationTargetRoot = resolveSqmRoot( sqmStatement, sqmStatement.getTarget().getManagedType().getJavaType() );
57+
}
58+
59+
public MutationSpecificationImpl(
60+
CriteriaDelete<T> criteriaQuery,
61+
SharedSessionContractImplementor session) {
62+
this.session = session;
63+
this.sqmStatement = (SqmDeleteStatement<T>) criteriaQuery;
64+
this.mutationTargetRoot = resolveSqmRoot( sqmStatement, sqmStatement.getTarget().getManagedType().getJavaType() );
65+
}
66+
4767
@Override
4868
public Root<T> getRoot() {
4969
return mutationTargetRoot;

hibernate-core/src/main/java/org/hibernate/query/programmatic/internal/SelectionSpecificationImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ public SelectionSpecificationImpl(
6060
this( "from " + determineEntityName( rootEntityType, session ), rootEntityType, session );
6161
}
6262

63+
public SelectionSpecificationImpl(
64+
CriteriaQuery<T> criteriaQuery,
65+
SharedSessionContractImplementor session) {
66+
this.resultType = criteriaQuery.getResultType();
67+
this.session = session;
68+
this.sqmStatement = (SqmSelectStatement<T>) criteriaQuery;
69+
this.sqmRoot = extractRoot( sqmStatement, resultType, "criteria query" );
70+
}
71+
6372
@Override
6473
public Root<T> getRoot() {
6574
return sqmRoot;

hibernate-core/src/test/java/org/hibernate/orm/test/query/dynamic/SimpleQuerySpecificationTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,27 @@ void testRootEntityForm(SessionFactoryScope factoryScope) {
168168
assertThat( sqlCollector.getSqlQueries().get( 0 ) ).contains( " order by be1_0.position" );
169169
}
170170

171+
@Test
172+
void testCriteriaForm(SessionFactoryScope factoryScope) {
173+
final SQLStatementInspector sqlCollector = factoryScope.getCollectingStatementInspector();
174+
175+
factoryScope.inTransaction( (session) -> {
176+
sqlCollector.clear();
177+
var criteriaBuilder = session.getCriteriaBuilder();
178+
var query = criteriaBuilder.createQuery( BasicEntity.class );
179+
var entity = query.from( BasicEntity.class );
180+
query.select( entity );
181+
query.where( criteriaBuilder.like( entity.get( BasicEntity_.name ), "%" ) );
182+
session.createSelectionSpecification( query )
183+
.addOrdering( Order.asc( BasicEntity_.position ) )
184+
.createQuery()
185+
.getResultList();
186+
} );
187+
188+
assertThat( sqlCollector.getSqlQueries() ).hasSize( 1 );
189+
assertThat( sqlCollector.getSqlQueries().get( 0 ) ).contains( " order by be1_0.position" );
190+
}
191+
171192
@Test
172193
void testBaseParameters(SessionFactoryScope factoryScope) {
173194
final SQLStatementInspector sqlCollector = factoryScope.getCollectingStatementInspector();

0 commit comments

Comments
 (0)