1010import org .hibernate .metamodel .model .domain .DomainType ;
1111import org .hibernate .metamodel .model .domain .ManagedDomainType ;
1212import org .hibernate .metamodel .model .domain .PersistentAttribute ;
13+ import org .hibernate .metamodel .model .domain .SimpleDomainType ;
1314
1415import java .util .HashMap ;
1516import java .util .Map ;
@@ -26,18 +27,30 @@ public class AttributeNodeImpl<J,V,K>
2627 extends AbstractGraphNode <J >
2728 implements AttributeNodeImplementor <J > {
2829 private final PersistentAttribute <?, J > attribute ;
30+ private final DomainType <V > valueGraphType ;
31+ private final SimpleDomainType <K > keyGraphType ;
2932
3033 private SubGraphImplementor <V > valueSubgraph ;
3134 private SubGraphImplementor <K > keySubgraph ;
3235
33- public <X > AttributeNodeImpl (PersistentAttribute <X , J > attribute , boolean mutable ) {
36+ static <X ,J > AttributeNodeImpl <J ,?,?> create (PersistentAttribute <X , J > attribute , boolean mutable ) {
37+ return new AttributeNodeImpl <>( attribute , mutable , attribute .getValueGraphType (), attribute .getKeyGraphType () );
38+ }
39+
40+ private <X > AttributeNodeImpl (
41+ PersistentAttribute <X , J > attribute , boolean mutable ,
42+ DomainType <V > valueGraphType , SimpleDomainType <K > keyGraphType ) {
3443 super ( mutable );
3544 this .attribute = attribute ;
45+ this .valueGraphType = valueGraphType ;
46+ this .keyGraphType = keyGraphType ;
3647 }
3748
3849 private AttributeNodeImpl (AttributeNodeImpl <J ,V ,K > that , boolean mutable ) {
3950 super ( mutable );
4051 attribute = that .attribute ;
52+ valueGraphType = that .valueGraphType ;
53+ keyGraphType = that .keyGraphType ;
4154 valueSubgraph = that .valueSubgraph == null ? null : that .valueSubgraph .makeCopy ( mutable );
4255 keySubgraph = that .keySubgraph == null ? null : that .keySubgraph .makeCopy ( mutable );
4356 }
@@ -66,21 +79,14 @@ public SubGraphImplementor<K> getKeySubGraph() {
6679 public SubGraphImplementor <V > makeSubGraph () {
6780 verifyMutability ();
6881 if ( valueSubgraph == null ) {
69- final ManagedDomainType <?> managedType = asManagedType ( attribute .getValueGraphType () );
70- @ SuppressWarnings ("unchecked" )
71- final ManagedDomainType <V > valueGraphType = (ManagedDomainType <V >) managedType ;
72- final SubGraphImplementor <V > graph = new SubGraphImpl <>( valueGraphType , true );
73- valueSubgraph = graph ;
74- return graph ;
75- }
76- else {
77- return valueSubgraph ;
82+ valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
7883 }
84+ return valueSubgraph ;
7985 }
8086
8187 @ Override
8288 public <S > SubGraphImplementor <S > makeSubGraph (Class <S > subtype ) {
83- final ManagedDomainType <? > managedType = asManagedType ( attribute . getValueGraphType () );
89+ final ManagedDomainType <V > managedType = asManagedType ( valueGraphType );
8490 if ( !managedType .getBindableJavaType ().isAssignableFrom ( subtype ) ) {
8591 throw new IllegalArgumentException ( "Not a subtype: " + subtype .getName () );
8692 }
@@ -93,7 +99,7 @@ public <S> SubGraphImplementor<S> makeSubGraph(Class<S> subtype) {
9399
94100 @ Override
95101 public <S > SubGraphImplementor <S > makeSubGraph (ManagedDomainType <S > subtype ) {
96- final ManagedDomainType <? > managedType = asManagedType ( attribute . getValueGraphType () );
102+ final ManagedDomainType <V > managedType = asManagedType ( valueGraphType );
97103 final Class <S > javaType = subtype .getBindableJavaType ();
98104 if ( !managedType .getBindableJavaType ().isAssignableFrom ( javaType ) ) {
99105 throw new IllegalArgumentException ( "Not a subtype: " + javaType .getName () );
@@ -108,22 +114,17 @@ public <S> SubGraphImplementor<S> makeSubGraph(ManagedDomainType<S> subtype) {
108114 @ Override
109115 public SubGraphImplementor <K > makeKeySubGraph () {
110116 verifyMutability ();
117+ checkMap ();
111118 if ( keySubgraph == null ) {
112- final ManagedDomainType <?> managedType = asManagedType ( attribute .getKeyGraphType () );
113- @ SuppressWarnings ("unchecked" )
114- final ManagedDomainType <K > keyGraphType = (ManagedDomainType <K >) managedType ;
115- final SubGraphImplementor <K > graph = new SubGraphImpl <>( keyGraphType , true );
116- keySubgraph = graph ;
117- return graph ;
118- }
119- else {
120- return keySubgraph ;
119+ keySubgraph = new SubGraphImpl <>( asManagedType ( keyGraphType ), true );
121120 }
121+ return keySubgraph ;
122122 }
123123
124124 @ Override
125125 public <S > SubGraphImplementor <S > makeKeySubGraph (Class <S > subtype ) {
126- final ManagedDomainType <?> type = asManagedType ( attribute .getKeyGraphType () );
126+ checkMap ();
127+ final ManagedDomainType <K > type = asManagedType ( keyGraphType );
127128 if ( !type .getBindableJavaType ().isAssignableFrom ( subtype ) ) {
128129 throw new IllegalArgumentException ( "Not a key subtype: " + subtype .getName () );
129130 }
@@ -136,7 +137,8 @@ public <S> SubGraphImplementor<S> makeKeySubGraph(Class<S> subtype) {
136137
137138 @ Override
138139 public <S > SubGraphImplementor <S > makeKeySubGraph (ManagedDomainType <S > subtype ) {
139- final ManagedDomainType <?> type = asManagedType ( attribute .getKeyGraphType () );
140+ checkMap ();
141+ final ManagedDomainType <K > type = asManagedType ( keyGraphType );
140142 final Class <S > javaType = subtype .getBindableJavaType ();
141143 if ( !type .getBindableJavaType ().isAssignableFrom ( javaType ) ) {
142144 throw new IllegalArgumentException ( "Not a key subtype: " + javaType .getName () );
@@ -148,15 +150,32 @@ public <S> SubGraphImplementor<S> makeKeySubGraph(ManagedDomainType<S> subtype)
148150 return (SubGraphImplementor <S >) result ;
149151 }
150152
151- private static <T > ManagedDomainType <T > asManagedType (DomainType <T > domainType ) {
153+ private void checkMap () {
154+ if ( keyGraphType == null ) {
155+ throw new CannotContainSubGraphException ( "Attribute '" + description () + "' is not a Map" );
156+ }
157+ }
158+
159+ private <T > ManagedDomainType <T > asManagedType (DomainType <T > domainType ) {
152160 if ( domainType instanceof ManagedDomainType <T > managedDomainType ) {
153161 return managedDomainType ;
154162 }
155163 else {
156- throw new CannotContainSubGraphException ( "Not a managed domain type: " + domainType .getTypeName () );
164+ throw new CannotContainSubGraphException ( "Attribute '" + description ()
165+ + "' is of type '" + domainType .getTypeName ()
166+ + "' which is not a managed type" );
157167 }
158168 }
159169
170+ private String description () {
171+ return attribute .getDeclaringType ().getTypeName () + "." + attribute .getName ();
172+ }
173+
174+ @ Override
175+ public String toString () {
176+ return "AttributeNode[" + description () + "]" ;
177+ }
178+
160179 @ Override
161180 public AttributeNodeImplementor <J > makeCopy (boolean mutable ) {
162181 return !mutable && !isMutable () ? this : new AttributeNodeImpl <>( this , mutable );
0 commit comments