Skip to content

Commit f530548

Browse files
committed
Graphpocalypse: major revision/refactoring of EntityGraph support
- fix up a bunch of generic typing issues - deprecate some old / obsolete operations - finally implement addTreatedSubgraph()
1 parent ef398e6 commit f530548

27 files changed

+692
-745
lines changed

hibernate-core/src/main/java/org/hibernate/graph/AttributeNode.java

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package org.hibernate.graph;
66

77
import java.util.Map;
8-
import jakarta.persistence.Subgraph;
98

109
import org.hibernate.metamodel.model.domain.PersistentAttribute;
1110

@@ -20,20 +19,8 @@ public interface AttributeNode<J> extends GraphNode<J>, jakarta.persistence.Attr
2019

2120
PersistentAttribute<?, J> getAttributeDescriptor();
2221

23-
Map<Class<? extends J>, SubGraph<? extends J>> getSubGraphs();
24-
Map<Class<? extends J>, SubGraph<? extends J>> getKeySubGraphs();
25-
26-
@Override
27-
@SuppressWarnings({"unchecked", "rawtypes"})
28-
default Map<Class, Subgraph> getSubgraphs() {
29-
return (Map) getSubGraphs();
30-
}
31-
32-
@Override
33-
@SuppressWarnings({"unchecked", "rawtypes"})
34-
default Map<Class, Subgraph> getKeySubgraphs() {
35-
return (Map) getKeySubGraphs();
36-
}
22+
Map<Class<? extends J>, ? extends SubGraph<? extends J>> getSubGraphs();
23+
Map<Class<? extends J>, ? extends SubGraph<? extends J>> getKeySubGraphs();
3724

3825
<S extends J> void addSubGraph(Class<S> subType, SubGraph<S> subGraph);
3926
<S extends J> void addKeySubGraph(Class<S> subType, SubGraph<S> subGraph);

hibernate-core/src/main/java/org/hibernate/graph/CannotContainSubGraphException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import org.hibernate.HibernateException;
88

99
/**
10-
* Indicates an attempt was made to add a (key)? sub-graph to an
11-
* attribute type that does not support (key)? sub-graphs.
10+
* Indicates an attempt was made to add a (key)? subgraph to an
11+
* attribute type that does not support (key)? subgraphs.
1212
*
1313
* @author Steve Ebersole
1414
*/

hibernate-core/src/main/java/org/hibernate/graph/EntityGraphs.java

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -31,40 +31,38 @@ public final class EntityGraphs {
3131
* Merges multiple entity graphs into a single graph that specifies the
3232
* fetching/loading of all attributes the input graphs specify.
3333
*
34-
* @param <T> Root entity type of the query and graph.
34+
* @param <T> Root entity type of the query and graph.
3535
*
36-
* @param em EntityManager to use to create the new merged graph.
36+
* @param entityManager EntityManager to use to create the new merged graph.
3737
* @param rootType Root type of the entity for which the graph is being merged.
38-
* @param graphs Graphs to merge.
38+
* @param graphs Graphs to merge.
3939
*
40-
* @return The merged graph.
40+
* @return The merged graph.
4141
*/
42-
@SuppressWarnings("unchecked")
43-
public static <T> EntityGraph<T> merge(EntityManager em, Class<T> rootType, EntityGraph<T>... graphs) {
44-
return merge( (SessionImplementor) em, rootType, (Object[]) graphs );
42+
@SafeVarargs
43+
public static <T> EntityGraph<T> merge(EntityManager entityManager, Class<T> rootType, EntityGraph<T>... graphs) {
44+
return mergeInternal( (SessionImplementor) entityManager, rootType, graphs );
4545
}
4646

4747
@SafeVarargs
4848
public static <T> EntityGraph<T> merge(Session session, Class<T> rootType, Graph<T>... graphs) {
49-
return merge( (SessionImplementor) session, rootType, (Object[]) graphs );
49+
return mergeInternal( (SessionImplementor) session, rootType, graphs );
5050
}
5151

5252
@SafeVarargs
5353
public static <T> EntityGraph<T> merge(SessionImplementor session, Class<T> rootType, GraphImplementor<T>... graphs) {
54-
return merge( session, rootType, (Object[]) graphs );
54+
return mergeInternal( session, rootType, graphs );
5555
}
5656

57-
@SuppressWarnings("unchecked")
58-
private static <T> EntityGraph<T> merge(SessionImplementor session, Class<T> rootType, Object... graphs) {
59-
RootGraphImplementor<T> merged = session.createEntityGraph( rootType );
60-
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 );
6160
if ( graphs != null ) {
62-
for ( Object graph : graphs ) {
61+
for ( jakarta.persistence.Graph<T> graph : graphs ) {
6362
merged.merge( (GraphImplementor<T>) graph );
6463
}
6564

6665
}
67-
6866
return merged;
6967
}
7068

@@ -75,12 +73,14 @@ private static <T> EntityGraph<T> merge(SessionImplementor session, Class<T> roo
7573
* @param query The JPA Query
7674
* @param graph The graph to apply
7775
* @param semantic The semantic to use when applying the graph
76+
*
77+
* @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
7878
*/
79-
@SuppressWarnings("unchecked")
80-
public static List executeList(Query query, EntityGraph graph, GraphSemantic semantic) {
79+
@Deprecated(since = "7.0")
80+
public static @SuppressWarnings("rawtypes") List executeList(Query query, EntityGraph<?> graph, GraphSemantic semantic) {
8181
return query.unwrap( org.hibernate.query.Query.class )
82-
.applyGraph( (RootGraph) graph, semantic )
83-
.list();
82+
.applyGraph( (RootGraph<?>) graph, semantic )
83+
.getResultList();
8484
}
8585

8686
/**
@@ -94,10 +94,14 @@ public static List executeList(Query query, EntityGraph graph, GraphSemantic sem
9494
* @apiNote This signature assumes that the Query's return is an entity and that
9595
* the graph applies to that entity's type. JPA does not necessarily
9696
* require that, but it is by far the most common usage.
97+
*
98+
* @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
9799
*/
98-
@SuppressWarnings({"unused", "unchecked"})
100+
@Deprecated(since = "7.0")
99101
public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph, GraphSemantic semantic) {
100-
return executeList( (Query) query, graph, semantic );
102+
@SuppressWarnings("unchecked")
103+
org.hibernate.query.Query<R> unwrapped = query.unwrap( org.hibernate.query.Query.class );
104+
return unwrapped.setEntityGraph( graph, semantic ).getResultList();
101105
}
102106

103107
/**
@@ -110,12 +114,12 @@ public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph,
110114
* @param semanticJpaHintName See {@link GraphSemantic#fromHintName}
111115
*
112116
* @return The result list
117+
*
118+
* @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
113119
*/
114-
@SuppressWarnings({"unused", "unchecked"})
115-
public static List executeList(Query query, EntityGraph graph, String semanticJpaHintName) {
116-
return query.unwrap( org.hibernate.query.Query.class )
117-
.applyGraph( (RootGraph) graph, GraphSemantic.fromHintName( semanticJpaHintName ) )
118-
.list();
120+
@Deprecated(since = "7.0")
121+
public static @SuppressWarnings("rawtypes") List executeList(Query query, EntityGraph<?> graph, String semanticJpaHintName) {
122+
return executeList( query, graph, GraphSemantic.fromHintName( semanticJpaHintName ) );
119123
}
120124

121125
/**
@@ -129,10 +133,12 @@ public static List executeList(Query query, EntityGraph graph, String semanticJp
129133
* @apiNote This signature assumes that the Query's return is an entity and that
130134
* the graph applies to that entity's type. JPA does not necessarily
131135
* require that, but it is by far the most common usage.
136+
*
137+
* @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
132138
*/
133-
@SuppressWarnings({"unused", "unchecked"})
139+
@Deprecated(since = "7.0")
134140
public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph, String semanticJpaHintName) {
135-
return executeList( (Query) query, graph, semanticJpaHintName );
141+
return executeList( query, graph, GraphSemantic.fromHintName( semanticJpaHintName ) );
136142
}
137143

138144
/**
@@ -146,12 +152,12 @@ public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph,
146152
* entity graph applied to a query is {@link GraphSemantic#FETCH}.
147153
* This is simply knowledge from JPA EG discussions, nothing that
148154
* is specifically mentioned or discussed in the spec.
155+
*
156+
* @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
149157
*/
150-
@SuppressWarnings({"unused", "unchecked"})
151-
public static List executeList(Query query, EntityGraph graph) {
152-
return query.unwrap( org.hibernate.query.Query.class )
153-
.applyFetchGraph( (RootGraph) graph )
154-
.list();
158+
@Deprecated(since = "7.0")
159+
public static @SuppressWarnings("rawtypes") List executeList(Query query, EntityGraph<?> graph) {
160+
return executeList( query, graph, GraphSemantic.FETCH );
155161
}
156162

157163
/**
@@ -164,16 +170,14 @@ public static List executeList(Query query, EntityGraph graph) {
164170
* @apiNote This signature assumes that the Query's return is an entity and that
165171
* the graph applies to that entity's type. JPA does not necessarily
166172
* require that, but it is by far the most common usage.
173+
*
174+
* @deprecated Use {@link org.hibernate.query.SelectionQuery#setEntityGraph(EntityGraph, GraphSemantic)}
167175
*/
168-
@SuppressWarnings("unused")
176+
@Deprecated(since = "7.0")
169177
public static <R> List<R> executeList(TypedQuery<R> query, EntityGraph<R> graph) {
170178
return executeList( query, graph, GraphSemantic.FETCH );
171179
}
172180

173-
// todo : ? - we could add JPA's other Query execution methods
174-
// but really, I think unwrapping as Hibernate's Query and using our
175-
// "proprietary" methods is better (this class is "proprietary" too).
176-
177181
/**
178182
* Compares two entity graphs and returns {@code true} if they are equal,
179183
* ignoring attribute order.
@@ -191,8 +195,8 @@ public static <T> boolean areEqual(EntityGraph<T> a, EntityGraph<T> b) {
191195
return false;
192196
}
193197

194-
List<AttributeNode<?>> aNodes = a.getAttributeNodes();
195-
List<AttributeNode<?>> bNodes = b.getAttributeNodes();
198+
final List<AttributeNode<?>> aNodes = a.getAttributeNodes();
199+
final List<AttributeNode<?>> bNodes = b.getAttributeNodes();
196200

197201
if ( aNodes.size() != bNodes.size() ) {
198202
return false;
@@ -226,7 +230,8 @@ public static boolean areEqual(AttributeNode<?> a, AttributeNode<?> b) {
226230
return false;
227231
}
228232
if ( a.getAttributeName().equals( b.getAttributeName() ) ) {
229-
return areEqual( a.getSubgraphs(), b.getSubgraphs() ) && areEqual( a.getKeySubgraphs(), b.getKeySubgraphs() );
233+
return areEqual( a.getSubgraphs(), b.getSubgraphs() )
234+
&& areEqual( a.getKeySubgraphs(), b.getKeySubgraphs() );
230235
}
231236
else {
232237
return false;
@@ -237,7 +242,9 @@ public static boolean areEqual(AttributeNode<?> a, AttributeNode<?> b) {
237242
* Compares two entity subgraph maps and returns {@code true} if they are equal,
238243
* ignoring order.
239244
*/
240-
public static boolean areEqual(@SuppressWarnings("rawtypes") Map<Class, Subgraph> a, @SuppressWarnings("rawtypes") Map<Class, Subgraph> b) {
245+
public static boolean areEqual(
246+
@SuppressWarnings("rawtypes") Map<Class, Subgraph> a,
247+
@SuppressWarnings("rawtypes") Map<Class, Subgraph> b) {
241248
if ( a == b ) {
242249
return true;
243250
}
@@ -246,9 +253,9 @@ public static boolean areEqual(@SuppressWarnings("rawtypes") Map<Class, Subgraph
246253
}
247254

248255
@SuppressWarnings("rawtypes")
249-
Set<Class> aKeys = a.keySet();
256+
final Set<Class> aKeys = a.keySet();
250257
@SuppressWarnings("rawtypes")
251-
Set<Class> bKeys = b.keySet();
258+
final Set<Class> bKeys = b.keySet();
252259

253260
if ( aKeys.equals( bKeys ) ) {
254261
for ( Class<?> clazz : aKeys ) {
@@ -282,16 +289,16 @@ public static boolean areEqual(@SuppressWarnings("rawtypes") Subgraph a, @Suppre
282289
}
283290

284291
@SuppressWarnings("unchecked")
285-
List<AttributeNode<?>> aNodes = a.getAttributeNodes();
292+
final List<AttributeNode<?>> aNodes = a.getAttributeNodes();
286293
@SuppressWarnings("unchecked")
287-
List<AttributeNode<?>> bNodes = b.getAttributeNodes();
294+
final List<AttributeNode<?>> bNodes = b.getAttributeNodes();
288295

289296
if ( aNodes.size() != bNodes.size() ) {
290297
return false;
291298
}
292299

293300
for ( AttributeNode<?> aNode : aNodes ) {
294-
String attributeName = aNode.getAttributeName();
301+
final String attributeName = aNode.getAttributeName();
295302
AttributeNode<?> bNode = null;
296303
for ( AttributeNode<?> bCandidate : bNodes ) {
297304
if ( attributeName.equals( bCandidate.getAttributeName() ) ) {

0 commit comments

Comments
 (0)