Skip to content

Commit 000a041

Browse files
committed
HHH-19096 Adjust SelectionQuery#setEntityGraph(..) to accept entity graphs of supertypes
1 parent ee18033 commit 000a041

File tree

7 files changed

+102
-8
lines changed

7 files changed

+102
-8
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ default Query<R> setPage(Page page) {
915915
Query<R> setHint(String hintName, Object value);
916916

917917
@Override
918-
Query<R> setEntityGraph(EntityGraph<R> graph, GraphSemantic semantic);
918+
Query<R> setEntityGraph(EntityGraph<? super R> graph, GraphSemantic semantic);
919919

920920
@Override
921921
Query<R> enableFetchProfile(String profileName);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ default Stream<R> stream() {
293293
*
294294
* @since 6.3
295295
*/
296-
SelectionQuery<R> setEntityGraph(EntityGraph<R> graph, GraphSemantic semantic);
296+
SelectionQuery<R> setEntityGraph(EntityGraph<? super R> graph, GraphSemantic semantic);
297297

298298
/**
299299
* Enable the {@linkplain org.hibernate.annotations.FetchProfile fetch

hibernate-core/src/main/java/org/hibernate/query/spi/AbstractQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public QueryImplementor<R> setHint(String hintName, Object value) {
128128
}
129129

130130
@Override
131-
public QueryImplementor<R> setEntityGraph(EntityGraph<R> graph, GraphSemantic semantic) {
131+
public QueryImplementor<R> setEntityGraph(EntityGraph<? super R> graph, GraphSemantic semantic) {
132132
super.setEntityGraph( graph, semantic );
133133
return this;
134134
}

hibernate-core/src/main/java/org/hibernate/query/spi/AbstractSelectionQuery.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,8 @@ public SelectionQuery<R> setHint(String hintName, Object value) {
372372
}
373373

374374
@Override
375-
public SelectionQuery<R> setEntityGraph(EntityGraph<R> graph, GraphSemantic semantic) {
376-
applyGraph( (RootGraphImplementor<R>) graph, semantic );
375+
public SelectionQuery<R> setEntityGraph(EntityGraph<? super R> graph, GraphSemantic semantic) {
376+
applyGraph( (RootGraphImplementor<? super R>) graph, semantic );
377377
return this;
378378
}
379379

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ public SqmQueryImplementor<R> setHint(String hintName, Object value) {
810810
}
811811

812812
@Override
813-
public Query<R> setEntityGraph(EntityGraph<R> graph, GraphSemantic semantic) {
813+
public Query<R> setEntityGraph(EntityGraph<? super R> graph, GraphSemantic semantic) {
814814
super.setEntityGraph( graph, semantic );
815815
return this;
816816
}

hibernate-core/src/main/java/org/hibernate/query/sqm/spi/DelegatingSqmSelectionQueryImplementor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public Optional<R> uniqueResultOptional() {
157157
}
158158

159159
@Override
160-
public SqmSelectionQueryImplementor<R> setEntityGraph(EntityGraph<R> graph, GraphSemantic semantic) {
160+
public SqmSelectionQueryImplementor<R> setEntityGraph(EntityGraph<? super R> graph, GraphSemantic semantic) {
161161
getDelegate().setEntityGraph( graph, semantic );
162162
return this;
163163
}

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/fetchprofile/NewGraphTest.java

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
import org.hibernate.engine.spi.SessionFactoryImplementor;
1010
import org.hibernate.graph.GraphSemantic;
1111
import org.hibernate.graph.RootGraph;
12+
import org.hibernate.query.SelectionQuery;
1213
import org.hibernate.testing.orm.junit.DomainModel;
1314
import org.hibernate.testing.orm.junit.SessionFactory;
1415
import org.hibernate.testing.orm.junit.SessionFactoryScope;
1516
import org.junit.jupiter.api.Test;
1617

18+
import java.util.HashSet;
19+
import java.util.List;
1720
import java.util.Set;
1821

1922
import static jakarta.persistence.FetchType.LAZY;
@@ -22,7 +25,8 @@
2225
import static org.junit.jupiter.api.Assertions.assertTrue;
2326

2427
@SessionFactory
25-
@DomainModel(annotatedClasses = {NewGraphTest.class, NewGraphTest.E.class, NewGraphTest.F.class, NewGraphTest.G.class, NewGraphTest.H.class})
28+
@DomainModel(annotatedClasses = {NewGraphTest.class, NewGraphTest.E.class, NewGraphTest.F.class, NewGraphTest.G.class, NewGraphTest.H.class,
29+
NewGraphTest.A.class, NewGraphTest.Aa.class, NewGraphTest.B.class})
2630
public class NewGraphTest {
2731

2832
@Test void testByIdEntityGraph(SessionFactoryScope scope) {
@@ -276,6 +280,66 @@ public class NewGraphTest {
276280
assertTrue( isInitialized( ee.f ) );
277281
}
278282

283+
@Test
284+
void subTypeEntityGraph(SessionFactoryScope scope) {
285+
scope.inTransaction( s -> {
286+
A a = new A();
287+
Aa aa = new Aa();
288+
B b1 = new B();
289+
B b2 = new B();
290+
B b3 = new B();
291+
b1.a = a;
292+
a.bs = new HashSet<>();
293+
a.bs.add( b1 );
294+
295+
b2.a = aa;
296+
aa.bs = new HashSet<>();
297+
aa.bs.add( b2 );
298+
299+
b3.a = aa;
300+
aa.bss = new HashSet<>();
301+
aa.bss.add( b3 );
302+
303+
s.persist( a );
304+
s.persist( aa );
305+
s.persist( b1 );
306+
s.persist( b2 );
307+
s.persist( b3 );
308+
} );
309+
310+
A a = scope.fromSession( s ->
311+
s.createSelectionQuery( "from A", A.class )
312+
.setMaxResults( 1 )
313+
.getSingleResult() );
314+
assertFalse( isInitialized( a.bs ) );
315+
316+
List<Aa> as = scope.fromSession( s -> {
317+
SelectionQuery<Aa> query = s.createSelectionQuery( "from Aa", Aa.class );
318+
RootGraph<A> graph = s.createEntityGraph(A.class);
319+
graph.addAttributeNodes("bs");
320+
return query
321+
.setEntityGraph( graph, GraphSemantic.FETCH )
322+
.getResultList();
323+
} );
324+
for ( Aa el : as ) {
325+
assertTrue( isInitialized( el.bs ) );
326+
assertFalse( isInitialized( el.bss ) );
327+
}
328+
329+
as = scope.fromSession( s -> {
330+
SelectionQuery<Aa> query = s.createSelectionQuery( "from Aa", Aa.class );
331+
RootGraph<Aa> graph = s.createEntityGraph(Aa.class);
332+
graph.addAttributeNodes("bs", "bss");
333+
return query
334+
.setEntityGraph( graph, GraphSemantic.FETCH )
335+
.getResultList();
336+
} );
337+
for ( Aa el : as ) {
338+
assertTrue( isInitialized( el.bs ) );
339+
assertTrue( isInitialized( el.bss ) );
340+
}
341+
}
342+
279343
@Entity(name = "E")
280344
static class E {
281345
@Id @GeneratedValue
@@ -307,4 +371,34 @@ static class H {
307371
Long id;
308372
@ManyToOne G g;
309373
}
374+
375+
@Entity(name = "A")
376+
static class A {
377+
@Id @GeneratedValue
378+
Long id;
379+
380+
@OneToMany(mappedBy = "a")
381+
Set<B> bs;
382+
}
383+
384+
@Entity(name = "Aa")
385+
static class Aa extends A {
386+
@Id @GeneratedValue
387+
Long id;
388+
389+
@OneToMany(mappedBy = "aa")
390+
Set<B> bss;
391+
}
392+
393+
@Entity(name = "B")
394+
static class B {
395+
@Id @GeneratedValue
396+
Long id;
397+
398+
@ManyToOne(fetch = LAZY)
399+
A a;
400+
401+
@ManyToOne(fetch = LAZY)
402+
Aa aa;
403+
}
310404
}

0 commit comments

Comments
 (0)