55package org .hibernate .graph .internal ;
66
77import jakarta .persistence .metamodel .Attribute ;
8+ import org .hibernate .AssertionFailure ;
89import org .hibernate .graph .CannotContainSubGraphException ;
910import org .hibernate .graph .spi .AttributeNodeImplementor ;
1011import org .hibernate .graph .spi .SubGraphImplementor ;
1415import org .hibernate .metamodel .model .domain .PersistentAttribute ;
1516import org .hibernate .metamodel .model .domain .PluralPersistentAttribute ;
1617import org .hibernate .metamodel .model .domain .SimpleDomainType ;
18+ import org .hibernate .metamodel .model .domain .SingularPersistentAttribute ;
1719
1820import java .util .HashMap ;
1921import java .util .Map ;
3234 * @author Steve Ebersole
3335 * @author Gavin King
3436 */
35- public class AttributeNodeImpl <J , E , K >
37+ public abstract class AttributeNodeImpl <J , E , K >
3638 extends AbstractGraphNode <J >
3739 implements AttributeNodeImplementor <J , E , K > {
38- private final PersistentAttribute <?, J > attribute ;
39- private final DomainType <E > valueGraphType ;
40- private final SimpleDomainType <K > keyGraphType ;
4140
42- private SubGraphImplementor <E > valueSubgraph ;
43- private SubGraphImplementor <K > keySubgraph ;
41+ protected final PersistentAttribute <?, J > attribute ;
42+ protected final DomainType <E > valueGraphType ;
43+ protected final SimpleDomainType <K > keyGraphType ;
4444
45- static <X ,J > AttributeNodeImpl <J ,?,?> create (PersistentAttribute <X , J > attribute , boolean mutable ) {
46- return new AttributeNodeImpl <>( attribute , mutable , attribute .getValueGraphType (), attribute .getKeyGraphType () );
45+ protected SubGraphImplementor <E > valueSubgraph ;
46+ protected SubGraphImplementor <K > keySubgraph ;
47+
48+ static <J > AttributeNodeImpl <J ,?,?> create (
49+ PersistentAttribute <?, J > attribute , boolean mutable ) {
50+ if ( attribute instanceof PluralPersistentAttribute <?, J , ?> pluralAttribute ) {
51+ return create ( pluralAttribute , mutable );
52+ }
53+ else if ( attribute instanceof SingularPersistentAttribute <?, J > singularAttribute ) {
54+ return new SingularAttributeNodeImpl <>( singularAttribute , mutable ,
55+ singularAttribute .getValueGraphType () );
56+ }
57+ else {
58+ throw new AssertionFailure ( "Unrecognized attribute type: " + attribute );
59+ }
60+ }
61+
62+ static <J ,E > AttributeNodeImpl <J ,E ,?> create (
63+ PluralPersistentAttribute <?, J , E > attribute , boolean mutable ) {
64+ if ( attribute instanceof MapPersistentAttribute <?, ?, ?> mapAttribute ) {
65+ return create ( attribute , mapAttribute , mutable );
66+ }
67+ else {
68+ return new PluralAttributeNodeImpl <>( attribute , mutable ,
69+ attribute .getValueGraphType () );
70+ }
4771 }
4872
49- static <X ,J ,E > AttributeNodeImpl <J ,E ,?> create (PluralPersistentAttribute <X , J , E > attribute , boolean mutable ) {
50- return new AttributeNodeImpl <>( attribute , mutable , attribute .getValueGraphType (), attribute .getKeyGraphType () );
73+ static <K ,V > AttributeNodeImpl <Map <K ,V >,V ,K > create (
74+ MapPersistentAttribute <?, K , V > attribute , boolean mutable ) {
75+ return new MapAttributeNodeImpl <>( attribute , attribute , mutable ,
76+ attribute .getValueGraphType (), attribute .getKeyGraphType () );
5177 }
5278
53- static <X ,K ,V > AttributeNodeImpl <Map <K ,V >,V ,K > create (MapPersistentAttribute <X , K , V > attribute , boolean mutable ) {
54- return new AttributeNodeImpl <>( attribute , mutable , attribute .getValueGraphType (), attribute .getKeyGraphType () );
79+ private static <J ,K ,V > AttributeNodeImpl <J ,V ,K > create (
80+ PluralPersistentAttribute <?, J , V > plural , MapPersistentAttribute <?, K , ?> attribute , boolean mutable ) {
81+ return new MapAttributeNodeImpl <>( plural , attribute , mutable ,
82+ plural .getValueGraphType (), attribute .getKeyGraphType () );
5583 }
5684
57- private < X > AttributeNodeImpl (
58- PersistentAttribute <X , J > attribute , boolean mutable ,
85+ AttributeNodeImpl (
86+ PersistentAttribute <? , J > attribute , boolean mutable ,
5987 DomainType <E > valueGraphType , SimpleDomainType <K > keyGraphType ) {
6088 super ( mutable );
6189 this .attribute = attribute ;
6290 this .valueGraphType = valueGraphType ;
6391 this .keyGraphType = keyGraphType ;
6492 }
6593
66- private AttributeNodeImpl (AttributeNodeImpl <J , E ,K > that , boolean mutable ) {
94+ private AttributeNodeImpl (AttributeNodeImpl <J , E , K > that , boolean mutable ) {
6795 super ( mutable );
6896 attribute = that .attribute ;
6997 valueGraphType = that .valueGraphType ;
@@ -72,6 +100,101 @@ private AttributeNodeImpl(AttributeNodeImpl<J, E,K> that, boolean mutable) {
72100 keySubgraph = that .keySubgraph == null ? null : that .keySubgraph .makeCopy ( mutable );
73101 }
74102
103+ private static class SingularAttributeNodeImpl <J > extends AttributeNodeImpl <J , J , Void > {
104+ private SingularAttributeNodeImpl (
105+ SingularPersistentAttribute <?,J > attribute ,
106+ boolean mutable ,
107+ DomainType <J > valueGraphType ) {
108+ super ( attribute , mutable , valueGraphType , null );
109+ }
110+
111+ private SingularAttributeNodeImpl (AttributeNodeImpl <J , J , Void > that , boolean mutable ) {
112+ super ( that , mutable );
113+ }
114+
115+ @ Override
116+ public SubGraphImplementor <J > addSingularSubgraph () {
117+ checkToOne ();
118+ verifyMutability ();
119+ if ( valueSubgraph == null ) {
120+ valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
121+ }
122+ return valueSubgraph ;
123+ }
124+
125+ @ Override
126+ public AttributeNodeImplementor <J , J , Void > makeCopy (boolean mutable ) {
127+ return !mutable && !isMutable () ? this : new SingularAttributeNodeImpl <>( this , mutable );
128+ }
129+ }
130+
131+ private static class PluralAttributeNodeImpl <J ,E > extends AttributeNodeImpl <J , E , Void > {
132+ private PluralAttributeNodeImpl (
133+ PluralPersistentAttribute <?,J ,E > attribute ,
134+ boolean mutable ,
135+ DomainType <E > valueGraphType ) {
136+ super ( attribute , mutable , valueGraphType , null );
137+ }
138+
139+ private PluralAttributeNodeImpl (AttributeNodeImpl <J , E , Void > that , boolean mutable ) {
140+ super ( that , mutable );
141+ }
142+
143+ @ Override
144+ public SubGraphImplementor <E > addElementSubgraph () {
145+ checkToMany ();
146+ verifyMutability ();
147+ if ( valueSubgraph == null ) {
148+ valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
149+ }
150+ return valueSubgraph ;
151+ }
152+
153+ @ Override
154+ public AttributeNodeImplementor <J , E , Void > makeCopy (boolean mutable ) {
155+ return !mutable && !isMutable () ? this : new PluralAttributeNodeImpl <>( this , mutable );
156+ }
157+ }
158+
159+ static class MapAttributeNodeImpl <J ,K ,V > extends AttributeNodeImpl <J , V , K > {
160+ private MapAttributeNodeImpl (
161+ PluralPersistentAttribute <?,J ,V > pluralAttribute ,
162+ @ SuppressWarnings ("unused" ) // a "witness" that this is really a Map
163+ MapPersistentAttribute <?,K ,?> attribute ,
164+ boolean mutable ,
165+ DomainType <V > valueGraphType , SimpleDomainType <K > keyGraphType ) {
166+ super ( pluralAttribute , mutable , valueGraphType , keyGraphType );
167+ }
168+
169+ private MapAttributeNodeImpl (AttributeNodeImpl <J , V , K > that , boolean mutable ) {
170+ super ( that , mutable );
171+ }
172+
173+ @ Override
174+ public SubGraphImplementor <K > addKeySubgraph () {
175+ verifyMutability ();
176+ if ( keySubgraph == null ) {
177+ keySubgraph = new SubGraphImpl <>( asManagedType ( keyGraphType ), true );
178+ }
179+ return keySubgraph ;
180+ }
181+
182+ @ Override
183+ public SubGraphImplementor <V > addElementSubgraph () {
184+ checkToMany ();
185+ verifyMutability ();
186+ if ( valueSubgraph == null ) {
187+ valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
188+ }
189+ return valueSubgraph ;
190+ }
191+
192+ @ Override
193+ public AttributeNodeImplementor <J , V , K > makeCopy (boolean mutable ) {
194+ return !mutable && !isMutable () ? this : new MapAttributeNodeImpl <>( this , mutable );
195+ }
196+ }
197+
75198 @ Override
76199 public String getAttributeName () {
77200 return getAttributeDescriptor ().getName ();
@@ -84,6 +207,7 @@ public PersistentAttribute<?, J> getAttributeDescriptor() {
84207
85208 @ Override
86209 public SubGraphImplementor <E > addValueSubgraph () {
210+ verifyMutability ();
87211 // this one is intentionally lenient and disfavored
88212 if ( valueSubgraph == null ) {
89213 valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
@@ -93,42 +217,27 @@ public SubGraphImplementor<E> addValueSubgraph() {
93217
94218 @ Override
95219 public SubGraphImplementor <J > addSingularSubgraph () {
96- checkToOne ();
97- if ( valueSubgraph == null ) {
98- valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
99- }
100- // Safe cast, in this case E = J
101- // TODO: would be more elegant to separate singularSubgraph vs elementSubgraph fields
102- //noinspection unchecked
103- return (SubGraphImplementor <J >) valueSubgraph ;
220+ throw new UnsupportedOperationException ("Not a singular attribute node" );
104221 }
105222
106223 @ Override
107224 public SubGraphImplementor <E > addElementSubgraph () {
108- checkToMany ();
109- if ( valueSubgraph == null ) {
110- valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
111- }
112- return valueSubgraph ;
225+ throw new UnsupportedOperationException ( "Not a collection-valued attribute node" );
113226 }
114227
115228 @ Override
116229 public SubGraphImplementor <K > addKeySubgraph () {
117- checkMap ();
118- if ( keySubgraph == null ) {
119- keySubgraph = new SubGraphImpl <>( asManagedType ( keyGraphType ), true );
120- }
121- return keySubgraph ;
230+ throw new UnsupportedOperationException ( "Not a Map-valued attribute node" );
122231 }
123232
124- private void checkToOne () {
233+ protected void checkToOne () {
125234 final Attribute .PersistentAttributeType attributeType = attribute .getPersistentAttributeType ();
126235 if ( attributeType != MANY_TO_ONE && attributeType != ONE_TO_ONE && attributeType != EMBEDDED ) {
127236 throw new CannotContainSubGraphException ( "Attribute '" + attribute .getName () + "' is not a to-one association" );
128237 }
129238 }
130239
131- private void checkToMany () {
240+ protected void checkToMany () {
132241 final Attribute .PersistentAttributeType attributeType = attribute .getPersistentAttributeType ();
133242 if ( attributeType != MANY_TO_MANY && attributeType != ONE_TO_MANY ) {
134243 throw new CannotContainSubGraphException ( "Attribute '" + attribute .getName () + "' is not a to-many association" );
@@ -187,7 +296,7 @@ private void checkMap() {
187296 }
188297 }
189298
190- private <T > ManagedDomainType <T > asManagedType (DomainType <T > domainType ) {
299+ protected <T > ManagedDomainType <T > asManagedType (DomainType <T > domainType ) {
191300 if ( domainType instanceof ManagedDomainType <T > managedDomainType ) {
192301 return managedDomainType ;
193302 }
@@ -208,16 +317,10 @@ public String toString() {
208317 }
209318
210319 @ Override
211- public AttributeNodeImplementor <J , E , K > makeCopy (boolean mutable ) {
212- return !mutable && !isMutable () ? this : new AttributeNodeImpl <>( this , mutable );
213- }
214-
215- @ Override
216- public void merge (AttributeNodeImplementor <J , E , K > other ) {
217- assert other .isMutable () == isMutable ();
218- assert other .getAttributeDescriptor () == attribute ;
219- final AttributeNodeImpl <J , E , K > that = (AttributeNodeImpl <J , E , K >) other ;
220- final SubGraphImplementor <E > otherValueSubgraph = that .valueSubgraph ;
320+ public void merge (AttributeNodeImplementor <J , E , K > that ) {
321+ assert that .isMutable () == isMutable ();
322+ assert that .getAttributeDescriptor () == attribute ;
323+ final SubGraphImplementor <E > otherValueSubgraph = that .getValueSubgraph ();
221324 if ( otherValueSubgraph != null ) {
222325 if ( valueSubgraph == null ) {
223326 valueSubgraph = otherValueSubgraph .makeCopy ( isMutable () );
@@ -227,7 +330,7 @@ public void merge(AttributeNodeImplementor<J, E, K> other) {
227330 valueSubgraph .mergeInternal ( otherValueSubgraph );
228331 }
229332 }
230- final SubGraphImplementor <K > otherKeySubgraph = that .keySubgraph ;
333+ final SubGraphImplementor <K > otherKeySubgraph = that .getKeySubgraph () ;
231334 if ( otherKeySubgraph != null ) {
232335 if ( keySubgraph == null ) {
233336 keySubgraph = otherKeySubgraph .makeCopy ( isMutable () );
@@ -262,4 +365,14 @@ public Map<Class<?>, SubGraphImplementor<?>> getKeySubGraphs() {
262365 return map ;
263366 }
264367 }
368+
369+ @ Override
370+ public SubGraphImplementor <E > getValueSubgraph () {
371+ return valueSubgraph ;
372+ }
373+
374+ @ Override
375+ public SubGraphImplementor <K > getKeySubgraph () {
376+ return keySubgraph ;
377+ }
265378}
0 commit comments