Skip to content

Commit eede2b7

Browse files
committed
Graphpocalypse: major revision/refactoring of EntityGraph support
- important simplification
1 parent 35fba77 commit eede2b7

File tree

9 files changed

+271
-219
lines changed

9 files changed

+271
-219
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
*/
55
package org.hibernate.graph;
66

7-
import java.util.Map;
87

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

11+
import java.util.Map;
12+
1213
/**
1314
* Extends the JPA-defined {@link AttributeNode} with additional operations.
1415
*
@@ -26,8 +27,8 @@ public interface AttributeNode<J> extends GraphNode<J>, jakarta.persistence.Attr
2627
SubGraph<?> makeSubGraph();
2728
SubGraph<?> makeKeySubGraph();
2829

29-
<S> SubGraph<S> makeSubGraph(Class<S> type);
30-
<S> SubGraph<S> makeKeySubGraph(Class<S> type);
30+
<S> SubGraph<S> makeSubGraph(Class<S> subtype);
31+
<S> SubGraph<S> makeKeySubGraph(Class<S> subtype);
3132

3233
<S> SubGraph<S> makeSubGraph(ManagedDomainType<S> subtype);
3334
<S> SubGraph<S> makeKeySubGraph(ManagedDomainType<S> subtype);

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ private static <T> EntityGraph<T> mergeInternal(
6161
for ( jakarta.persistence.Graph<T> graph : graphs ) {
6262
merged.merge( (GraphImplementor<T>) graph );
6363
}
64-
6564
}
6665
return merged;
6766
}

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.hibernate.metamodel.model.domain.ManagedDomainType;
1212
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
1313
import org.hibernate.metamodel.model.domain.PersistentAttribute;
14+
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
1415

1516
/**
1617
* A container for {@link AttributeNode} references.
@@ -130,6 +131,8 @@ default <Y> AttributeNode<Y> addAttributeNode(Attribute<? super J, Y> attribute)
130131

131132
<Y extends J> SubGraph<Y> addTreatedSubGraph(Class<Y> type);
132133

134+
<Y extends J> SubGraph<Y> addTreatedSubGraph(ManagedDomainType<Y> type);
135+
133136
/**
134137
* Create and return a new (mutable) {@link SubGraph} associated with
135138
* the named {@link AttributeNode}.
@@ -151,18 +154,22 @@ default <Y> AttributeNode<Y> addAttributeNode(Attribute<? super J, Y> attribute)
151154

152155
<AJ> SubGraph<AJ> addSubGraph(PersistentAttribute<? super J, ? super AJ> attribute, Class<AJ> type);
153156

154-
<AJ> SubGraph<AJ> addSubGraph(MapPersistentAttribute<? super J, ? super AJ, ?> attribute, ManagedDomainType<AJ> type);
157+
<AJ> SubGraph<AJ> addSubGraph(PersistentAttribute<? super J, ? super AJ> attribute, ManagedDomainType<AJ> type);
158+
159+
<AJ> SubGraph<AJ> addElementSubGraph(PluralPersistentAttribute<? super J, ?, ? super AJ> attribute, Class<AJ> type);
160+
161+
<AJ> SubGraph<AJ> addElementSubGraph(PluralPersistentAttribute<? super J, ?, ? super AJ> attribute, ManagedDomainType<AJ> type);
155162

156163
@Deprecated
157164
<AJ> SubGraph<AJ> addKeySubGraph(String attributeName);
158165

159166
<AJ> SubGraph<AJ> addKeySubGraph(String attributeName, Class<AJ> type);
160167

161-
<AJ> SubGraph<AJ> addKeySubGraph(PersistentAttribute<? super J, ? super AJ> attribute, ManagedDomainType<AJ> type);
168+
<AJ> SubGraph<AJ> addKeySubGraph(MapPersistentAttribute<? super J, ? super AJ, ?> attribute, ManagedDomainType<AJ> type);
162169

163170
@Override
164171
default <Y> SubGraph<Y> addTreatedSubgraph(Attribute<? super J, ? super Y> attribute, Class<Y> type) {
165-
return addSubGraph( (PersistentAttribute<? super J, ? super Y>) attribute, type );
172+
return addSubGraph( (PersistentAttribute<? super J, ? super Y>) attribute ).addTreatedSubGraph( type );
166173
}
167174

168175
@Override
@@ -172,7 +179,7 @@ default <X> SubGraph<X> addSubgraph(Attribute<? super J, X> attribute) {
172179

173180
@Override
174181
default <X> SubGraph<? extends X> addSubgraph(Attribute<? super J, X> attribute, Class<? extends X> type) {
175-
return addSubGraph( (PersistentAttribute<? super J, X>) attribute, type );
182+
return addSubGraph( (PersistentAttribute<? super J, X>) attribute ).addTreatedSubGraph( type );
176183
}
177184

178185
@Override
@@ -182,7 +189,7 @@ default <X> SubGraph<X> addSubgraph(String name) {
182189

183190
@Override
184191
default <X> SubGraph<X> addSubgraph(String name, Class<X> type) {
185-
return addSubGraph( name, type );
192+
return addSubGraph( name ).addTreatedSubGraph( type );
186193
}
187194

188195
@Override
@@ -192,7 +199,7 @@ default <X> SubGraph<X> addKeySubgraph(String name) {
192199

193200
@Override
194201
default <X> SubGraph<X> addKeySubgraph(String name, Class<X> type) {
195-
return addKeySubGraph( name, type );
202+
return addKeySubGraph( name ).addTreatedSubGraph( type );
196203
}
197204

198205
/**

hibernate-core/src/main/java/org/hibernate/graph/internal/AbstractGraph.java

Lines changed: 92 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.hibernate.metamodel.model.domain.ManagedDomainType;
2424
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
2525
import org.hibernate.metamodel.model.domain.PersistentAttribute;
26+
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
2627
import org.hibernate.query.sqm.SqmPathSource;
2728

2829
import jakarta.persistence.metamodel.Attribute;
@@ -39,19 +40,21 @@
3940
public abstract class AbstractGraph<J> extends AbstractGraphNode<J> implements GraphImplementor<J> {
4041

4142
private final ManagedDomainType<J> managedType;
43+
private final Map<Class<?>, SubGraphImplementor<?>> subgraphs = new HashMap<>(1);
4244
private Map<PersistentAttribute<? super J,?>, AttributeNodeImplementor<?>> attributeNodes;
43-
private List<SubGraphImplementor<? extends J>> subgraphs;
4445

4546
public AbstractGraph(ManagedDomainType<J> managedType, boolean mutable) {
4647
super( mutable );
4748
this.managedType = managedType;
49+
if ( this instanceof SubGraphImplementor<?> self ) {
50+
subgraphs.put( managedType.getJavaType(), self );
51+
}
4852
}
4953

5054
protected AbstractGraph(ManagedDomainType<J> managedType, GraphImplementor<? super J> graph, boolean mutable) {
5155
this( managedType, mutable );
5256
attributeNodes = new HashMap<>( graph.getAttributeNodesByAttribute().size() );
53-
graph.getAttributeNodesByAttribute()
54-
.forEach( (attribute, node) -> attributeNodes.put( attribute, node.makeCopy( mutable ) ) );
57+
mergeInternal( graph, mutable );
5558
}
5659

5760
protected AbstractGraph(GraphImplementor<J> graph, boolean mutable) {
@@ -76,42 +79,63 @@ public RootGraphImplementor<J> makeRootGraph(String name, boolean mutable) {
7679
}
7780

7881
@Override
79-
public void merge(GraphImplementor<J> graph) {
82+
public void merge(GraphImplementor<? super J> graph) {
83+
merge( graph, true );
84+
}
85+
86+
@Override
87+
public void merge(GraphImplementor<? super J> graph, boolean mutable) {
8088
if ( graph != null ) {
8189
verifyMutability();
82-
graph.getAttributeNodesByAttribute().forEach( (attribute, node) -> {
83-
final AttributeNodeImplementor<?> existingNode = findAttributeNode( attribute );
84-
if ( existingNode != null ) {
85-
// keep the local one, but merge in the incoming one
86-
mergeNode( node, existingNode );
90+
mergeInternal( graph, mutable );
91+
}
92+
}
93+
94+
private void mergeInternal(GraphImplementor<? super J> graph, boolean mutable) {
95+
graph.getAttributeNodesByAttribute().forEach( (attribute, node) -> {
96+
final AttributeNodeImplementor<?> existingNode = findAttributeNode( attribute );
97+
if ( existingNode != null ) {
98+
// keep the local one, but merge in the incoming one
99+
mergeNode( node, existingNode, mutable );
100+
}
101+
else {
102+
addAttributeNode( attribute, node.makeCopy( mutable ), mutable );
103+
}
104+
} );
105+
graph.getSubGraphMap().forEach( (type, subgraph) -> {
106+
if ( subgraph != graph ) {
107+
final SubGraphImplementor<?> existing = subgraphs.get( type );
108+
if ( existing != null ) {
109+
existing.merge( (SubGraphImplementor) subgraph, mutable );
87110
}
88111
else {
89-
addAttributeNode( attribute, node.makeCopy( true ) );
112+
subgraphs.put( type, subgraph.makeCopy( mutable ) );
90113
}
91-
} );
92-
}
114+
}
115+
} );
93116
}
94117

95-
private static <T> void mergeNode(AttributeNodeImplementor<?> node, AttributeNodeImplementor<T> existingNode) {
118+
private static <T> void mergeNode(
119+
AttributeNodeImplementor<?> node, AttributeNodeImplementor<T> existingNode, boolean mutable) {
96120
if ( existingNode.getAttributeDescriptor() == node.getAttributeDescriptor() ) {
97121
@SuppressWarnings("unchecked") // safe, we just checked
98122
final AttributeNodeImplementor<T> castNode = (AttributeNodeImplementor<T>) node;
99-
existingNode.merge( castNode );
123+
existingNode.merge( castNode, mutable );
100124
}
101125
else {
102126
throw new AssertionFailure( "Attributes should have been identical" );
103127
}
104128
}
105129

106-
private <T> void addAttributeNode(PersistentAttribute<? super J, ?> attribute, AttributeNodeImplementor<T> node) {
130+
private <T> void addAttributeNode(
131+
PersistentAttribute<? super J, ?> attribute, AttributeNodeImplementor<T> node, boolean mutable) {
107132
final AttributeNodeImplementor<T> attributeNode = getNodeForPut( node.getAttributeDescriptor() );
108133
if ( attributeNode == null ) {
109134
attributeNodes.put( attribute, node );
110135
}
111136
else {
112137
// we assume the subgraph has been properly copied if needed
113-
node.getSubGraphMap().forEach( (subtype, subgraph) -> attributeNode.addSubGraph( subgraph ) );
114-
node.getKeySubGraphMap().forEach( (subtype, subgraph) -> attributeNode.addKeySubGraph( subgraph ) );
138+
node.merge( attributeNode, mutable );
115139
}
116140
}
117141

@@ -126,11 +150,13 @@ public <AJ> AttributeNodeImplementor<AJ> findAttributeNode(String attributeName)
126150
@SuppressWarnings("unchecked") // The JPA API is unsafe by nature
127151
final PersistentAttribute<? super J, AJ> persistentAttribute = (PersistentAttribute<? super J, AJ>) attribute;
128152
final AttributeNodeImplementor<AJ> node = attribute == null ? null : findAttributeNode( persistentAttribute );
129-
if ( node == null && subgraphs != null ) {
130-
for ( SubGraphImplementor<? extends J> subgraph : subgraphs ) {
131-
final AttributeNodeImplementor<AJ> subgraphNode = subgraph.findAttributeNode( attributeName );
132-
if ( subgraphNode != null ) {
133-
return subgraphNode;
153+
if ( node == null ) {
154+
for ( SubGraphImplementor<?> subgraph : subgraphs.values() ) {
155+
if ( subgraph != this ) {
156+
final AttributeNodeImplementor<AJ> subgraphNode = subgraph.findAttributeNode( attributeName );
157+
if ( subgraphNode != null ) {
158+
return subgraphNode;
159+
}
134160
}
135161
}
136162
return null;
@@ -272,12 +298,22 @@ public <AJ> SubGraphImplementor<AJ> addSubGraph(PersistentAttribute<? super J, ?
272298
}
273299

274300
@Override
275-
public <AJ> SubGraphImplementor<AJ> addSubGraph(MapPersistentAttribute<? super J, ? super AJ, ?> attribute, ManagedDomainType<AJ> subtype) {
301+
public <AJ> SubGraphImplementor<AJ> addSubGraph(PersistentAttribute<? super J, ? super AJ> attribute, ManagedDomainType<AJ> subtype) {
276302
return findOrCreateAttributeNode( attribute ).makeSubGraph( subtype );
277303
}
278304

279305
@Override
280-
public <AJ> SubGraphImplementor<AJ> addKeySubGraph(PersistentAttribute<? super J, ? super AJ> attribute, ManagedDomainType<AJ> subtype) {
306+
public <AJ> SubGraphImplementor<AJ> addElementSubGraph(PluralPersistentAttribute<? super J, ?, ? super AJ> attribute, Class<AJ> type) {
307+
return findOrCreateAttributeNode( attribute ).makeSubGraph( type );
308+
}
309+
310+
@Override
311+
public <AJ> SubGraphImplementor<AJ> addElementSubGraph(PluralPersistentAttribute<? super J, ?, ? super AJ> attribute, ManagedDomainType<AJ> type) {
312+
return findOrCreateAttributeNode( attribute ).makeSubGraph( type );
313+
}
314+
315+
@Override
316+
public <AJ> SubGraphImplementor<AJ> addKeySubGraph(MapPersistentAttribute<? super J, ? super AJ, ?> attribute, ManagedDomainType<AJ> subtype) {
281317
return findOrCreateAttributeNode( attribute ).makeKeySubGraph( subtype );
282318
}
283319

@@ -328,13 +364,38 @@ public <E> SubGraphImplementor<E> addTreatedElementSubgraph(
328364
}
329365

330366
@Override
331-
public <S extends J> SubGraphImplementor<S> addTreatedSubGraph(Class<S> type) {
332-
final ManagedDomainType<S> managedDomainType = getGraphedType().getMetamodel().managedType( type );
333-
final SubGraphImpl<S> subgraph = new SubGraphImpl<>( managedDomainType, this, true );
334-
if ( subgraphs == null ) {
335-
subgraphs = new ArrayList<>( 1 );
367+
public <S extends J> SubGraphImplementor<S> addTreatedSubGraph(ManagedDomainType<S> type) {
368+
final Class<S> javaType = type.getJavaType();
369+
final SubGraphImplementor<S> castSubgraph = subgraph( javaType );
370+
if ( castSubgraph == null ) {
371+
final SubGraphImpl<S> subgraph = new SubGraphImpl<>( type, true );
372+
subgraphs.put( javaType, subgraph );
373+
return subgraph;
336374
}
337-
subgraphs.add( subgraph );
338-
return subgraph;
375+
else {
376+
return castSubgraph;
377+
}
378+
}
379+
380+
private <S extends J> SubGraphImplementor<S> subgraph(Class<S> javaType) {
381+
final SubGraphImplementor<?> existing = subgraphs.get( javaType );
382+
if ( existing != null ) {
383+
@SuppressWarnings("unchecked")
384+
final SubGraphImplementor<S> castSubgraph = (SubGraphImplementor<S>) existing;
385+
return castSubgraph;
386+
}
387+
else {
388+
return null;
389+
}
390+
}
391+
392+
@Override
393+
public <S extends J> SubGraphImplementor<S> addTreatedSubGraph(Class<S> type) {
394+
return addTreatedSubGraph( getGraphedType().getMetamodel().managedType( type ) );
395+
}
396+
397+
@Override
398+
public Map<Class<?>, SubGraphImplementor<?>> getSubGraphMap() {
399+
return subgraphs;
339400
}
340401
}

0 commit comments

Comments
 (0)