4
4
*/
5
5
package org .hibernate .graph ;
6
6
7
+ import java .util .Arrays ;
7
8
import java .util .List ;
8
9
import java .util .Map ;
9
10
import java .util .Set ;
11
+ import java .util .stream .Stream ;
12
+
10
13
import jakarta .persistence .AttributeNode ;
11
14
import jakarta .persistence .EntityGraph ;
12
15
import jakarta .persistence .EntityManager ;
16
+ import jakarta .persistence .Graph ;
13
17
import jakarta .persistence .Query ;
14
18
import jakarta .persistence .Subgraph ;
15
19
import jakarta .persistence .TypedQuery ;
16
20
17
- import org .hibernate .Session ;
18
21
import org .hibernate .engine .spi .SessionImplementor ;
19
22
import org .hibernate .graph .spi .GraphImplementor ;
20
23
import org .hibernate .graph .spi .RootGraphImplementor ;
24
+ import org .hibernate .query .SelectionQuery ;
21
25
22
26
/**
23
27
* A collection of {@link EntityGraph} utilities.
24
28
*
25
- * @apiNote These methods really belong inside other classes that we cannot modify .
29
+ * @apiNote These operations are things which are arguably missing from JPA .
26
30
*
27
31
* @author asusnjar
32
+ * @author Gavin King
28
33
*/
29
34
public final class EntityGraphs {
35
+
30
36
/**
31
37
* Merges multiple entity graphs into a single graph that specifies the
32
38
* fetching/loading of all attributes the input graphs specify.
33
39
*
34
40
* @param <T> Root entity type of the query and graph.
35
41
*
36
- * @param entityManager EntityManager to use to create the new merged graph.
37
- * @param rootType Root type of the entity for which the graph is being merged.
42
+ * @param entityManager {@code EntityManager} to use to create the new merged graph.
43
+ * @param root Root type of the entity for which the graph is being merged.
38
44
* @param graphs Graphs to merge.
39
45
*
40
46
* @return The merged graph.
41
47
*/
42
48
@ SafeVarargs
43
- public static <T > EntityGraph <T > merge (EntityManager entityManager , Class <T > rootType , EntityGraph <T >... graphs ) {
44
- return mergeInternal ( ( SessionImplementor ) entityManager , rootType , graphs );
49
+ public static <T > EntityGraph <T > merge (EntityManager entityManager , Class <T > root , Graph <T >... graphs ) {
50
+ return merge ( entityManager , root , Arrays . stream ( graphs ) );
45
51
}
46
52
47
- @ SafeVarargs
48
- public static <T > EntityGraph <T > merge (Session session , Class <T > rootType , Graph <T >... graphs ) {
49
- return mergeInternal ( (SessionImplementor ) session , rootType , graphs );
53
+ /**
54
+ * Merges multiple entity graphs into a single graph that specifies the
55
+ * fetching/loading of all attributes the input graphs specify.
56
+ *
57
+ * @param <T> Root entity type of the query and graph.
58
+ *
59
+ * @param entityManager {@code EntityManager} to use to create the new merged graph.
60
+ * @param root Root type of the entity for which the graph is being merged.
61
+ * @param graphs Graphs to merge.
62
+ *
63
+ * @return The merged graph.
64
+ *
65
+ * @since 7.0
66
+ */
67
+ public static <T > EntityGraph <T > merge (EntityManager entityManager , Class <T > root , List <? extends Graph <T >> graphs ) {
68
+ return merge ( entityManager , root , graphs .stream () );
50
69
}
51
70
52
- @ SafeVarargs
53
- public static <T > EntityGraph <T > merge (SessionImplementor session , Class <T > rootType , GraphImplementor <T >... graphs ) {
54
- return mergeInternal ( session , rootType , graphs );
71
+ /**
72
+ * Merges multiple entity graphs into a single graph that specifies the
73
+ * fetching/loading of all attributes the input graphs specify.
74
+ *
75
+ * @param <T> Root entity type of the query and graph.
76
+ *
77
+ * @param entityManager {@code EntityManager} to use to create the new merged graph.
78
+ * @param root Root type of the entity for which the graph is being merged.
79
+ * @param graphs Graphs to merge.
80
+ *
81
+ * @return The merged graph.
82
+ *
83
+ * @since 7.0
84
+ */
85
+ public static <T > EntityGraph <T > merge (EntityManager entityManager , Class <T > root , Stream <? extends Graph <T >> graphs ) {
86
+ final RootGraphImplementor <T > merged = ((SessionImplementor ) entityManager ).createEntityGraph ( root );
87
+ graphs .forEach ( graph -> merged .merge ( (GraphImplementor <T >) graph ) );
88
+ return merged ;
55
89
}
56
90
57
- private static <T > EntityGraph <T > mergeInternal (
58
- SessionImplementor session , Class <T > rootType , jakarta .persistence .Graph <T >[] graphs ) {
59
- final RootGraphImplementor <T > merged = session .createEntityGraph ( rootType );
60
- if ( graphs != null ) {
61
- for ( jakarta .persistence .Graph <T > graph : graphs ) {
62
- merged .merge ( (GraphImplementor <T >) graph );
63
- }
64
- }
65
- return merged ;
91
+ /**
92
+ * Convenience method to apply the given graph to the given query
93
+ * without the need for a cast when working with JPA API.
94
+ *
95
+ * @param query The JPA {@link TypedQuery}
96
+ * @param graph The JPA {@link EntityGraph} to apply
97
+ * @param semantic The semantic to use when applying the graph
98
+ *
99
+ * @see SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)
100
+ *
101
+ * @since 7.0
102
+ */
103
+ public static <R > void setGraph (TypedQuery <R > query , EntityGraph <R > graph , GraphSemantic semantic ) {
104
+ ((org .hibernate .query .Query <R >) query ).setEntityGraph ( graph , semantic );
105
+ }
106
+
107
+ /**
108
+ * Convenience method to apply the given load graph to the given
109
+ * query without the need for a cast when working with JPA API.
110
+ *
111
+ * @param query The JPA {@link TypedQuery}
112
+ * @param graph The JPA {@link EntityGraph} to apply
113
+ *
114
+ * @since 7.0
115
+ */
116
+ public static <R > void setLoadGraph (TypedQuery <R > query , EntityGraph <R > graph ) {
117
+ setGraph ( query , graph , GraphSemantic .LOAD );
118
+ }
119
+
120
+ /**
121
+ * Convenience method to apply the given fetch graph to the given
122
+ * query without the need for a cast when working with JPA API.
123
+ *
124
+ * @param query The JPA {@link TypedQuery}
125
+ * @param graph The JPA {@link EntityGraph} to apply
126
+ *
127
+ * @since 7.0
128
+ */
129
+ public static <R > void setFetchGraph (TypedQuery <R > query , EntityGraph <R > graph ) {
130
+ setGraph ( query , graph , GraphSemantic .FETCH );
131
+ }
132
+
133
+ /**
134
+ * Allows a treated subgraph to ve created for a {@link Subgraph}, since the
135
+ * JPA-standard operation {@link EntityGraph#addTreatedSubgraph(Class)} is
136
+ * declared by {@link EntityGraph}.
137
+ *
138
+ * @param graph any {@linkplain Graph root graph or subgraph}
139
+ * @param subtype the treated (narrowed) type
140
+ *
141
+ * @since 7.0
142
+ */
143
+ public <S > Subgraph <S > addTreatedSubgraph (Graph <? super S > graph , Class <S > subtype ) {
144
+ return ((org .hibernate .graph .Graph <? super S >) graph ).addTreatedSubGraph ( subtype );
66
145
}
67
146
68
147
/**
@@ -73,7 +152,7 @@ private static <T> EntityGraph<T> mergeInternal(
73
152
* @param graph The graph to apply
74
153
* @param semantic The semantic to use when applying the graph
75
154
*
76
- * @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
155
+ * @deprecated Since it is not type safe and returns a raw type
77
156
*/
78
157
@ Deprecated (since = "7.0" )
79
158
public static @ SuppressWarnings ("rawtypes" ) List executeList (Query query , EntityGraph <?> graph , GraphSemantic semantic ) {
@@ -94,7 +173,7 @@ private static <T> EntityGraph<T> mergeInternal(
94
173
* the graph applies to that entity's type. JPA does not necessarily
95
174
* require that, but it is by far the most common usage.
96
175
*
97
- * @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph( EntityGraph, GraphSemantic)}
176
+ * @deprecated Use {@link #setGraph(TypedQuery, EntityGraph, GraphSemantic)} instead
98
177
*/
99
178
@ Deprecated (since = "7.0" )
100
179
public static <R > List <R > executeList (TypedQuery <R > query , EntityGraph <R > graph , GraphSemantic semantic ) {
@@ -114,7 +193,7 @@ public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph,
114
193
*
115
194
* @return The result list
116
195
*
117
- * @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
196
+ * @deprecated Since it is not type safe, returns a raw type, and accepts a string
118
197
*/
119
198
@ Deprecated (since = "7.0" )
120
199
public static @ SuppressWarnings ("rawtypes" ) List executeList (Query query , EntityGraph <?> graph , String semanticJpaHintName ) {
@@ -133,7 +212,7 @@ public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph,
133
212
* the graph applies to that entity's type. JPA does not necessarily
134
213
* require that, but it is by far the most common usage.
135
214
*
136
- * @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic) }
215
+ * @deprecated Since it accepts a string instead of {@link GraphSemantic}
137
216
*/
138
217
@ Deprecated (since = "7.0" )
139
218
public static <R > List <R > executeList (TypedQuery <R > query , EntityGraph <R > graph , String semanticJpaHintName ) {
@@ -152,7 +231,7 @@ public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph,
152
231
* This is simply knowledge from JPA EG discussions, nothing that
153
232
* is specifically mentioned or discussed in the spec.
154
233
*
155
- * @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
234
+ * @deprecated Since it is not type safe and returns a raw type
156
235
*/
157
236
@ Deprecated (since = "7.0" )
158
237
public static @ SuppressWarnings ("rawtypes" ) List executeList (Query query , EntityGraph <?> graph ) {
@@ -170,7 +249,7 @@ public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph,
170
249
* the graph applies to that entity's type. JPA does not necessarily
171
250
* require that, but it is by far the most common usage.
172
251
*
173
- * @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
252
+ * @deprecated Use {@link #setFetchGraph(TypedQuery, EntityGraph)} instead
174
253
*/
175
254
@ Deprecated (since = "7.0" )
176
255
public static <R > List <R > executeList (TypedQuery <R > query , EntityGraph <R > graph ) {
@@ -276,7 +355,9 @@ public static boolean areEqual(
276
355
* Compares two entity subgraphs and returns {@code true} if they are equal,
277
356
* ignoring attribute order.
278
357
*/
279
- public static boolean areEqual (@ SuppressWarnings ("rawtypes" ) Subgraph a , @ SuppressWarnings ("rawtypes" ) Subgraph b ) {
358
+ public static boolean areEqual (
359
+ @ SuppressWarnings ("rawtypes" ) Subgraph a ,
360
+ @ SuppressWarnings ("rawtypes" ) Subgraph b ) {
280
361
if ( a == b ) {
281
362
return true ;
282
363
}
0 commit comments