Skip to content

Commit 24fe60e

Browse files
committed
Graphpocalypse: major revision/refactoring of EntityGraph support
- important simplification
1 parent 5687749 commit 24fe60e

File tree

9 files changed

+280
-206
lines changed

9 files changed

+280
-206
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: 90 additions & 30 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,8 +40,8 @@
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 );
@@ -50,8 +51,7 @@ public AbstractGraph(ManagedDomainType<J> managedType, boolean mutable) {
5051
protected AbstractGraph(ManagedDomainType<J> managedType, GraphImplementor<? super J> graph, boolean mutable) {
5152
this( managedType, mutable );
5253
attributeNodes = new HashMap<>( graph.getAttributeNodesByAttribute().size() );
53-
graph.getAttributeNodesByAttribute()
54-
.forEach( (attribute, node) -> attributeNodes.put( attribute, node.makeCopy( mutable ) ) );
54+
mergeInternal( graph, mutable );
5555
}
5656

5757
protected AbstractGraph(GraphImplementor<J> graph, boolean mutable) {
@@ -76,42 +76,61 @@ public RootGraphImplementor<J> makeRootGraph(String name, boolean mutable) {
7676
}
7777

7878
@Override
79-
public void merge(GraphImplementor<J> graph) {
79+
public void merge(GraphImplementor<? super J> graph) {
80+
merge( graph, true );
81+
}
82+
83+
@Override
84+
public void merge(GraphImplementor<? super J> graph, boolean mutable) {
8085
if ( graph != null ) {
8186
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 );
87-
}
88-
else {
89-
addAttributeNode( attribute, node.makeCopy( true ) );
90-
}
91-
} );
87+
mergeInternal( graph, mutable );
9288
}
9389
}
9490

95-
private static <T> void mergeNode(AttributeNodeImplementor<?> node, AttributeNodeImplementor<T> existingNode) {
91+
private void mergeInternal(GraphImplementor<? super J> graph, boolean mutable) {
92+
graph.getAttributeNodesByAttribute().forEach( (attribute, node) -> {
93+
final AttributeNodeImplementor<?> existingNode = findAttributeNode( attribute );
94+
if ( existingNode != null ) {
95+
// keep the local one, but merge in the incoming one
96+
mergeNode( node, existingNode, mutable );
97+
}
98+
else {
99+
addAttributeNode( attribute, node.makeCopy( mutable ), mutable );
100+
}
101+
} );
102+
graph.getSubGraphMap().forEach( (type, subgraph) -> {
103+
final SubGraphImplementor<?> existing = subgraphs.get( type );
104+
if ( existing != null ) {
105+
existing.merge( (SubGraphImplementor) subgraph, mutable );
106+
}
107+
else {
108+
subgraphs.put( type, subgraph.makeCopy( mutable ) );
109+
}
110+
} );
111+
}
112+
113+
private static <T> void mergeNode(
114+
AttributeNodeImplementor<?> node, AttributeNodeImplementor<T> existingNode, boolean mutable) {
96115
if ( existingNode.getAttributeDescriptor() == node.getAttributeDescriptor() ) {
97116
@SuppressWarnings("unchecked") // safe, we just checked
98117
final AttributeNodeImplementor<T> castNode = (AttributeNodeImplementor<T>) node;
99-
existingNode.merge( castNode );
118+
existingNode.merge( castNode, mutable );
100119
}
101120
else {
102121
throw new AssertionFailure( "Attributes should have been identical" );
103122
}
104123
}
105124

106-
private <T> void addAttributeNode(PersistentAttribute<? super J, ?> attribute, AttributeNodeImplementor<T> node) {
125+
private <T> void addAttributeNode(
126+
PersistentAttribute<? super J, ?> attribute, AttributeNodeImplementor<T> node, boolean mutable) {
107127
final AttributeNodeImplementor<T> attributeNode = getNodeForPut( node.getAttributeDescriptor() );
108128
if ( attributeNode == null ) {
109129
attributeNodes.put( attribute, node );
110130
}
111131
else {
112132
// 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 ) );
133+
node.merge( attributeNode, mutable );
115134
}
116135
}
117136

@@ -126,8 +145,8 @@ public <AJ> AttributeNodeImplementor<AJ> findAttributeNode(String attributeName)
126145
@SuppressWarnings("unchecked") // The JPA API is unsafe by nature
127146
final PersistentAttribute<? super J, AJ> persistentAttribute = (PersistentAttribute<? super J, AJ>) attribute;
128147
final AttributeNodeImplementor<AJ> node = attribute == null ? null : findAttributeNode( persistentAttribute );
129-
if ( node == null && subgraphs != null ) {
130-
for ( SubGraphImplementor<? extends J> subgraph : subgraphs ) {
148+
if ( node == null ) {
149+
for ( SubGraphImplementor<?> subgraph : subgraphs.values() ) {
131150
final AttributeNodeImplementor<AJ> subgraphNode = subgraph.findAttributeNode( attributeName );
132151
if ( subgraphNode != null ) {
133152
return subgraphNode;
@@ -272,12 +291,22 @@ public <AJ> SubGraphImplementor<AJ> addSubGraph(PersistentAttribute<? super J, ?
272291
}
273292

274293
@Override
275-
public <AJ> SubGraphImplementor<AJ> addSubGraph(MapPersistentAttribute<? super J, ? super AJ, ?> attribute, ManagedDomainType<AJ> subtype) {
294+
public <AJ> SubGraphImplementor<AJ> addSubGraph(PersistentAttribute<? super J, ? super AJ> attribute, ManagedDomainType<AJ> subtype) {
276295
return findOrCreateAttributeNode( attribute ).makeSubGraph( subtype );
277296
}
278297

279298
@Override
280-
public <AJ> SubGraphImplementor<AJ> addKeySubGraph(PersistentAttribute<? super J, ? super AJ> attribute, ManagedDomainType<AJ> subtype) {
299+
public <AJ> SubGraphImplementor<AJ> addElementSubGraph(PluralPersistentAttribute<? super J, ?, ? super AJ> attribute, Class<AJ> type) {
300+
return findOrCreateAttributeNode( attribute ).makeSubGraph( type );
301+
}
302+
303+
@Override
304+
public <AJ> SubGraphImplementor<AJ> addElementSubGraph(PluralPersistentAttribute<? super J, ?, ? super AJ> attribute, ManagedDomainType<AJ> type) {
305+
return findOrCreateAttributeNode( attribute ).makeSubGraph( type );
306+
}
307+
308+
@Override
309+
public <AJ> SubGraphImplementor<AJ> addKeySubGraph(MapPersistentAttribute<? super J, ? super AJ, ?> attribute, ManagedDomainType<AJ> subtype) {
281310
return findOrCreateAttributeNode( attribute ).makeKeySubGraph( subtype );
282311
}
283312

@@ -328,13 +357,44 @@ public <E> SubGraphImplementor<E> addTreatedElementSubgraph(
328357
}
329358

330359
@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 );
360+
public <S extends J> SubGraphImplementor<S> addTreatedSubGraph(ManagedDomainType<S> type) {
361+
if ( getGraphedType().equals( type ) ) {
362+
//noinspection unchecked
363+
return (SubGraphImplementor<S>) this;
364+
}
365+
else {
366+
final Class<S> javaType = type.getJavaType();
367+
final SubGraphImplementor<S> castSubgraph = subgraph( javaType );
368+
if ( castSubgraph == null ) {
369+
final SubGraphImpl<S> subgraph = new SubGraphImpl<>( type, true );
370+
subgraphs.put( javaType, subgraph );
371+
return subgraph;
372+
}
373+
else {
374+
return castSubgraph;
375+
}
376+
}
377+
}
378+
379+
private <S extends J> SubGraphImplementor<S> subgraph(Class<S> javaType) {
380+
final SubGraphImplementor<?> existing = subgraphs.get( javaType );
381+
if ( existing != null ) {
382+
@SuppressWarnings("unchecked")
383+
final SubGraphImplementor<S> castSubgraph = (SubGraphImplementor<S>) existing;
384+
return castSubgraph;
385+
}
386+
else {
387+
return null;
336388
}
337-
subgraphs.add( subgraph );
338-
return subgraph;
389+
}
390+
391+
@Override
392+
public <S extends J> SubGraphImplementor<S> addTreatedSubGraph(Class<S> type) {
393+
return addTreatedSubGraph( getGraphedType().getMetamodel().managedType( type ) );
394+
}
395+
396+
@Override
397+
public Map<Class<?>, SubGraphImplementor<?>> getSubGraphMap() {
398+
return subgraphs;
339399
}
340400
}

0 commit comments

Comments
 (0)