44 */
55package org .hibernate .graph .internal ;
66
7+ import java .util .Collections ;
78import java .util .HashMap ;
89import java .util .Locale ;
910import java .util .Map ;
2021import org .hibernate .metamodel .model .domain .SimpleDomainType ;
2122
2223import org .hibernate .metamodel .model .domain .internal .DomainModelHelper ;
24+
2325import org .jboss .logging .Logger ;
2426
2527import static java .util .Collections .emptyMap ;
@@ -35,24 +37,25 @@ public class AttributeNodeImpl<J>
3537 implements AttributeNodeImplementor <J > {
3638 private final PersistentAttribute <?, J > attribute ;
3739
38- private Map <Class <? extends J >, SubGraphImplementor <? extends J >> subGraphMap ;
3940 private Map <Class <? extends J >, SubGraphImplementor <? extends J >> keySubGraphMap ;
41+ private SubGraphImplementor <J > subgraph ;
42+
4043
4144 public <X > AttributeNodeImpl (PersistentAttribute <X , J > attribute , boolean mutable ) {
42- this (attribute , null , null , mutable );
45+ this ( attribute , null , null , mutable );
4346 }
4447
4548 /**
4649 * Intended only for use from making a copy
4750 */
4851 private AttributeNodeImpl (
4952 PersistentAttribute <?, J > attribute ,
50- Map < Class <? extends J >, SubGraphImplementor <? extends J >> subGraphMap ,
53+ SubGraphImplementor <J > subgraph ,
5154 Map <Class <? extends J >, SubGraphImplementor <? extends J >> keySubGraphMap ,
5255 boolean mutable ) {
5356 super ( mutable );
5457 this .attribute = attribute ;
55- this .subGraphMap = subGraphMap ;
58+ this .subgraph = subgraph ;
5659 this .keySubGraphMap = keySubGraphMap ;
5760 }
5861
@@ -68,7 +71,24 @@ public PersistentAttribute<?, J> getAttributeDescriptor() {
6871
6972 @ Override
7073 public Map <Class <? extends J >, SubGraphImplementor <? extends J >> getSubGraphMap () {
71- return subGraphMap == null ? emptyMap () : subGraphMap ;
74+ if ( this .subgraph == null ) {
75+ return emptyMap ();
76+ }
77+
78+ var subclassSubgraphs = subgraph .getSubclassSubgraphs ();
79+
80+ if ( subclassSubgraphs .isEmpty () ) {
81+ return Collections .singletonMap ( subgraph .getClassType (), subgraph );
82+ }
83+
84+ subclassSubgraphs .put ( subgraph .getClassType (), subgraph );
85+
86+ return subclassSubgraphs ;
87+ }
88+
89+ @ Override
90+ public SubGraphImplementor <J > getSubgraph () {
91+ return subgraph ;
7292 }
7393
7494 @ Override
@@ -91,12 +111,21 @@ public <S extends J> SubGraphImplementor<S> makeSubGraph(ManagedDomainType<S> su
91111 return internalMakeSubgraph ( subtype );
92112 }
93113
114+ @ SuppressWarnings ({"unchecked" })
94115 private <S extends J > SubGraphImplementor <S > internalMakeSubgraph (ManagedDomainType <S > type ) {
95116 assert type != null ;
117+
96118 log .debugf ( "Making sub-graph : ( (%s) %s )" , type .getTypeName (), getAttributeName () );
97- final SubGraphImplementor <S > subGraph = DomainModelHelper .makeSubGraph ( type , type .getBindableJavaType () );
98- internalAddSubGraph ( subGraph );
99- return subGraph ;
119+
120+ if ( this .subgraph == null ) {
121+ this .subgraph = new SubGraphImpl <>( valueGraphTypeAsManaged (), true );
122+ }
123+
124+ if ( type .equals ( valueGraphTypeAsManaged () ) ) {
125+ return (SubGraphImplementor <S >) this .subgraph ;
126+ }
127+
128+ return this .subgraph .addTreatedSubgraph ( type .getJavaType () );
100129 }
101130
102131 @ SuppressWarnings ("unchecked" )
@@ -122,17 +151,29 @@ private <T extends J> ManagedDomainType<T> valueGraphTypeAsManaged() {
122151 private <S extends J > SubGraphImplementor <S > internalMakeSubgraph (Class <S > subType ) {
123152 verifyMutability ();
124153 final ManagedDomainType <S > managedType = valueGraphTypeAsManaged ();
125- return internalMakeSubgraph ( findSubType ( managedType , subType == null ? managedType .getJavaType () : subType ) );
154+ return internalMakeSubgraph ( findSubType (
155+ managedType ,
156+ subType == null ? managedType .getJavaType () : subType
157+ ) );
126158 }
127159
128- protected void internalAddSubGraph (SubGraphImplementor <? extends J > subGraph ) {
160+ protected < S extends J > void internalAddSubGraph (SubGraphImplementor <S > subGraph ) {
129161 log .tracef ( "Adding sub-graph : ( (%s) %s )" , subGraph .getGraphedType ().getTypeName (), getAttributeName () );
130- if ( subGraphMap == null ) {
131- subGraphMap = new HashMap <>();
162+
163+ if ( this .subgraph == null ) {
164+ this .subgraph = new SubGraphImpl <>( valueGraphTypeAsManaged (), true );
132165 }
133- final SubGraphImplementor <? extends J > previous = subGraphMap .put ( subGraph .getClassType (), subGraph );
134- if ( previous != null ) {
135- log .debugf ( "Adding sub-graph [%s] over-wrote existing [%s]" , subGraph , previous );
166+
167+ ManagedDomainType <S > incomingSubGraphType = subGraph .getGraphedType ();
168+
169+ if ( incomingSubGraphType .equals ( this .subgraph .getGraphedType () ) ) {
170+ this .subgraph .merge ( subGraph );
171+ return ;
172+ }
173+
174+ if ( this .subgraph .getGraphedType ().getSubTypes ().contains ( incomingSubGraphType ) ) {
175+ var subclassSubgraph = this .subgraph .addTreatedSubgraph ( incomingSubGraphType .getBindableJavaType () );
176+ subclassSubgraph .merge ( subGraph );
136177 }
137178 }
138179
@@ -218,7 +259,10 @@ public <S extends J> void addKeySubGraph(Class<S> subType, SubGraph<S> subGraph)
218259 @ Override
219260 public AttributeNodeImplementor <J > makeCopy (boolean mutable ) {
220261 return new AttributeNodeImpl <>(
221- this .attribute , makeMapCopy ( mutable , subGraphMap ), makeMapCopy ( mutable , keySubGraphMap ), mutable
262+ this .attribute ,
263+ this .subgraph == null ? null : this .subgraph .makeCopy ( mutable ),
264+ makeMapCopy ( mutable , keySubGraphMap ),
265+ mutable
222266 );
223267 }
224268
@@ -230,32 +274,22 @@ private Map<Class<? extends J>, SubGraphImplementor<? extends J>> makeMapCopy(
230274 }
231275 else {
232276 return nodeMap .entrySet ().stream ()
233- .map (entry -> Map .entry ( entry .getKey (), entry .getValue ().makeCopy ( mutable ) ))
234- .collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue ) );
277+ .map ( entry -> Map .entry ( entry .getKey (), entry .getValue ().makeCopy ( mutable ) ) )
278+ .collect ( Collectors .toMap ( Map .Entry ::getKey , Map .Entry ::getValue ) );
235279 }
236280 }
237281
238282 @ Override
283+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
239284 public void merge (AttributeNodeImplementor <?> attributeNode ) {
240- attributeNode .visitSubGraphs (
241- (incomingSubType , incomingGraph ) -> {
242- SubGraphImplementor <?> existing ;
243- if ( subGraphMap == null ) {
244- subGraphMap = new HashMap <>();
245- existing = null ;
246- }
247- else {
248- existing = subGraphMap .get ( incomingSubType );
249- }
250285
251- if ( existing != null ) {
252- existing .merge ( (GraphImplementor ) incomingGraph );
253- }
254- else {
255- internalAddSubGraph ( (SubGraphImplementor ) incomingGraph .makeCopy ( true ) );
256- }
257- }
258- );
286+
287+ if ( this .subgraph != null ) {
288+ this .subgraph .merge ( (SubGraphImplementor ) attributeNode .getSubgraph () );
289+ }
290+ else {
291+ this .subgraph = (SubGraphImplementor ) attributeNode .getSubgraph ();
292+ }
259293
260294 attributeNode .visitKeySubGraphs (
261295 (incomingSubType , incomingGraph ) -> {
0 commit comments