66 */
77package org .hibernate .graph .internal ;
88
9+ import java .util .Collections ;
910import java .util .HashMap ;
1011import java .util .Locale ;
1112import java .util .Map ;
2223import org .hibernate .metamodel .model .domain .SimpleDomainType ;
2324
2425import org .hibernate .metamodel .model .domain .internal .DomainModelHelper ;
26+
2527import org .jboss .logging .Logger ;
2628
2729import static java .util .Collections .emptyMap ;
@@ -37,24 +39,25 @@ public class AttributeNodeImpl<J>
3739 implements AttributeNodeImplementor <J > {
3840 private final PersistentAttribute <?, J > attribute ;
3941
40- private Map <Class <? extends J >, SubGraphImplementor <? extends J >> subGraphMap ;
4142 private Map <Class <? extends J >, SubGraphImplementor <? extends J >> keySubGraphMap ;
43+ private SubGraphImplementor <J > subgraph ;
44+
4245
4346 public <X > AttributeNodeImpl (PersistentAttribute <X , J > attribute , boolean mutable ) {
44- this (attribute , null , null , mutable );
47+ this ( attribute , null , null , mutable );
4548 }
4649
4750 /**
4851 * Intended only for use from making a copy
4952 */
5053 private AttributeNodeImpl (
5154 PersistentAttribute <?, J > attribute ,
52- Map < Class <? extends J >, SubGraphImplementor <? extends J >> subGraphMap ,
55+ SubGraphImplementor <J > subgraph ,
5356 Map <Class <? extends J >, SubGraphImplementor <? extends J >> keySubGraphMap ,
5457 boolean mutable ) {
5558 super ( mutable );
5659 this .attribute = attribute ;
57- this .subGraphMap = subGraphMap ;
60+ this .subgraph = subgraph ;
5861 this .keySubGraphMap = keySubGraphMap ;
5962 }
6063
@@ -70,7 +73,24 @@ public PersistentAttribute<?, J> getAttributeDescriptor() {
7073
7174 @ Override
7275 public Map <Class <? extends J >, SubGraphImplementor <? extends J >> getSubGraphMap () {
73- return subGraphMap == null ? emptyMap () : subGraphMap ;
76+ if ( this .subgraph == null ) {
77+ return emptyMap ();
78+ }
79+
80+ var subclassSubgraphs = subgraph .getSubclassSubgraphs ();
81+
82+ if ( subclassSubgraphs .isEmpty () ) {
83+ return Collections .singletonMap ( subgraph .getClassType (), subgraph );
84+ }
85+
86+ subclassSubgraphs .put ( subgraph .getClassType (), subgraph );
87+
88+ return subclassSubgraphs ;
89+ }
90+
91+ @ Override
92+ public SubGraphImplementor <J > getSubgraph () {
93+ return subgraph ;
7494 }
7595
7696 @ Override
@@ -95,10 +115,18 @@ public <S extends J> SubGraphImplementor<S> makeSubGraph(ManagedDomainType<S> su
95115
96116 private <S extends J > SubGraphImplementor <S > internalMakeSubgraph (ManagedDomainType <S > type ) {
97117 assert type != null ;
118+
98119 log .debugf ( "Making sub-graph : ( (%s) %s )" , type .getTypeName (), getAttributeName () );
99- final SubGraphImplementor <S > subGraph = DomainModelHelper .makeSubGraph ( type , type .getBindableJavaType () );
100- internalAddSubGraph ( subGraph );
101- return subGraph ;
120+
121+ if ( this .subgraph == null ) {
122+ this .subgraph = new SubGraphImpl <>( valueGraphTypeAsManaged (), true );
123+ }
124+
125+ if ( type .equals ( valueGraphTypeAsManaged () ) ) {
126+ return (SubGraphImplementor ) this .subgraph ;
127+ }
128+
129+ return this .subgraph .addTreatedSubgraph ( type .getJavaType () );
102130 }
103131
104132 @ SuppressWarnings ("unchecked" )
@@ -124,18 +152,30 @@ private <T extends J> ManagedDomainType<T> valueGraphTypeAsManaged() {
124152 private <S extends J > SubGraphImplementor <S > internalMakeSubgraph (Class <S > subType ) {
125153 verifyMutability ();
126154 final ManagedDomainType <S > managedType = valueGraphTypeAsManaged ();
127- return internalMakeSubgraph ( findSubType ( managedType , subType == null ? managedType .getJavaType () : subType ) );
155+ return internalMakeSubgraph ( findSubType (
156+ managedType ,
157+ subType == null ? managedType .getJavaType () : subType
158+ ) );
128159 }
129160
130161 protected void internalAddSubGraph (SubGraphImplementor <? extends J > subGraph ) {
131162 log .tracef ( "Adding sub-graph : ( (%s) %s )" , subGraph .getGraphedType ().getTypeName (), getAttributeName () );
132- if ( subGraphMap == null ) {
133- subGraphMap = new HashMap <>();
163+
164+ if ( this .subgraph == null ) {
165+ this .subgraph = new SubGraphImpl <>( valueGraphTypeAsManaged (), true );
134166 }
135- final SubGraphImplementor <? extends J > previous = subGraphMap .put ( subGraph .getClassType (), subGraph );
136- if ( previous != null ) {
137- log .debugf ( "Adding sub-graph [%s] over-wrote existing [%s]" , subGraph , previous );
167+
168+ ManagedDomainType <?> incomingSubGraphType = subGraph .getGraphedType ();
169+
170+ if ( incomingSubGraphType .equals ( this .subgraph .getGraphedType () ) ) {
171+ this .subgraph .merge ( subGraph );
172+ return ;
173+ }
174+
175+ if ( this .subgraph .getGraphedType ().getSubTypes ().contains ( incomingSubGraphType ) ) {
176+ this .subgraph .addSubclassSubgraph ( subGraph );
138177 }
178+
139179 }
140180
141181 @ Override
@@ -220,7 +260,10 @@ public <S extends J> void addKeySubGraph(Class<S> subType, SubGraph<S> subGraph)
220260 @ Override
221261 public AttributeNodeImplementor <J > makeCopy (boolean mutable ) {
222262 return new AttributeNodeImpl <>(
223- this .attribute , makeMapCopy ( mutable , subGraphMap ), makeMapCopy ( mutable , keySubGraphMap ), mutable
263+ this .attribute ,
264+ this .subgraph == null ? null : this .subgraph .makeCopy ( mutable ),
265+ makeMapCopy ( mutable , keySubGraphMap ),
266+ mutable
224267 );
225268 }
226269
@@ -232,32 +275,21 @@ private Map<Class<? extends J>, SubGraphImplementor<? extends J>> makeMapCopy(
232275 }
233276 else {
234277 return nodeMap .entrySet ().stream ()
235- .map (entry -> Map .entry ( entry .getKey (), entry .getValue ().makeCopy ( mutable ) ))
236- .collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue ) );
278+ .map ( entry -> Map .entry ( entry .getKey (), entry .getValue ().makeCopy ( mutable ) ) )
279+ .collect ( Collectors .toMap ( Map .Entry ::getKey , Map .Entry ::getValue ) );
237280 }
238281 }
239282
240283 @ Override
241284 public void merge (AttributeNodeImplementor <?> attributeNode ) {
242- attributeNode .visitSubGraphs (
243- (incomingSubType , incomingGraph ) -> {
244- SubGraphImplementor <?> existing ;
245- if ( subGraphMap == null ) {
246- subGraphMap = new HashMap <>();
247- existing = null ;
248- }
249- else {
250- existing = subGraphMap .get ( incomingSubType );
251- }
252285
253- if ( existing != null ) {
254- existing .merge ( (GraphImplementor ) incomingGraph );
255- }
256- else {
257- internalAddSubGraph ( (SubGraphImplementor ) incomingGraph .makeCopy ( true ) );
258- }
259- }
260- );
286+
287+ if ( this .subgraph != null ) {
288+ this .subgraph .merge ( (SubGraphImplementor ) attributeNode .getSubgraph () );
289+ }
290+ else {
291+ this .subgraph = (SubGraphImplementor ) attributeNode .getSubgraph ();
292+ }
261293
262294 attributeNode .visitKeySubGraphs (
263295 (incomingSubType , incomingGraph ) -> {
0 commit comments