4
4
*/
5
5
package org .hibernate .graph .internal ;
6
6
7
- import jakarta .persistence .metamodel .ManagedType ;
7
+ import jakarta .persistence .metamodel .Attribute ;
8
8
import org .hibernate .graph .CannotContainSubGraphException ;
9
9
import org .hibernate .graph .spi .AttributeNodeImplementor ;
10
10
import org .hibernate .graph .spi .SubGraphImplementor ;
11
11
import org .hibernate .metamodel .model .domain .DomainType ;
12
12
import org .hibernate .metamodel .model .domain .ManagedDomainType ;
13
+ import org .hibernate .metamodel .model .domain .MapPersistentAttribute ;
13
14
import org .hibernate .metamodel .model .domain .PersistentAttribute ;
15
+ import org .hibernate .metamodel .model .domain .PluralPersistentAttribute ;
14
16
import org .hibernate .metamodel .model .domain .SimpleDomainType ;
15
17
16
18
import java .util .HashMap ;
17
19
import java .util .Map ;
18
20
21
+ import static jakarta .persistence .metamodel .Attribute .PersistentAttributeType .EMBEDDED ;
22
+ import static jakarta .persistence .metamodel .Attribute .PersistentAttributeType .MANY_TO_MANY ;
23
+ import static jakarta .persistence .metamodel .Attribute .PersistentAttributeType .MANY_TO_ONE ;
24
+ import static jakarta .persistence .metamodel .Attribute .PersistentAttributeType .ONE_TO_MANY ;
25
+ import static jakarta .persistence .metamodel .Attribute .PersistentAttributeType .ONE_TO_ONE ;
19
26
import static java .util .Collections .emptyMap ;
20
27
21
28
25
32
* @author Steve Ebersole
26
33
* @author Gavin King
27
34
*/
28
- public class AttributeNodeImpl <J ,V , K >
35
+ public class AttributeNodeImpl <J , E , K >
29
36
extends AbstractGraphNode <J >
30
- implements AttributeNodeImplementor <J > {
37
+ implements AttributeNodeImplementor <J , E , K > {
31
38
private final PersistentAttribute <?, J > attribute ;
32
- private final DomainType <V > valueGraphType ;
39
+ private final DomainType <E > valueGraphType ;
33
40
private final SimpleDomainType <K > keyGraphType ;
34
41
35
- private SubGraphImplementor <V > valueSubgraph ;
42
+ private SubGraphImplementor <E > valueSubgraph ;
36
43
private SubGraphImplementor <K > keySubgraph ;
37
44
38
45
static <X ,J > AttributeNodeImpl <J ,?,?> create (PersistentAttribute <X , J > attribute , boolean mutable ) {
39
46
return new AttributeNodeImpl <>( attribute , mutable , attribute .getValueGraphType (), attribute .getKeyGraphType () );
40
47
}
41
48
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 () );
51
+ }
52
+
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 () );
55
+ }
56
+
42
57
private <X > AttributeNodeImpl (
43
58
PersistentAttribute <X , J > attribute , boolean mutable ,
44
- DomainType <V > valueGraphType , SimpleDomainType <K > keyGraphType ) {
59
+ DomainType <E > valueGraphType , SimpleDomainType <K > keyGraphType ) {
45
60
super ( mutable );
46
61
this .attribute = attribute ;
47
62
this .valueGraphType = valueGraphType ;
48
63
this .keyGraphType = keyGraphType ;
49
64
}
50
65
51
- private AttributeNodeImpl (AttributeNodeImpl <J ,V ,K > that , boolean mutable ) {
66
+ private AttributeNodeImpl (AttributeNodeImpl <J , E ,K > that , boolean mutable ) {
52
67
super ( mutable );
53
68
attribute = that .attribute ;
54
69
valueGraphType = that .valueGraphType ;
@@ -68,52 +83,81 @@ public PersistentAttribute<?, J> getAttributeDescriptor() {
68
83
}
69
84
70
85
@ Override
71
- public SubGraphImplementor <V > getSubGraph () {
86
+ public SubGraphImplementor <E > addValueSubgraph () {
87
+ // this one is intentionally lenient and disfavored
88
+ if ( valueSubgraph == null ) {
89
+ valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
90
+ }
72
91
return valueSubgraph ;
73
92
}
74
93
75
94
@ Override
76
- public SubGraphImplementor <K > getKeySubGraph () {
77
- return keySubgraph ;
95
+ 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 ;
78
104
}
79
105
80
106
@ Override
81
- public SubGraphImplementor <V > makeSubGraph () {
82
- verifyMutability ();
107
+ public SubGraphImplementor <E > addElementSubgraph () {
108
+ checkToMany ();
83
109
if ( valueSubgraph == null ) {
84
110
valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
85
111
}
86
112
return valueSubgraph ;
87
113
}
88
114
89
115
@ Override
90
- public < S > SubGraphImplementor <S > makeSubGraph ( Class < S > subtype ) {
91
- final ManagedDomainType < V > managedType = asManagedType ( valueGraphType );
92
- if ( ! managedType . getBindableJavaType (). isAssignableFrom ( subtype ) ) {
93
- throw new IllegalArgumentException ( "Not a subtype: " + subtype . getName () );
116
+ public SubGraphImplementor <K > addKeySubgraph ( ) {
117
+ checkMap ( );
118
+ if ( keySubgraph == null ) {
119
+ keySubgraph = new SubGraphImpl <>( asManagedType ( keyGraphType ), true );
94
120
}
95
- @ SuppressWarnings ("unchecked" )
96
- final Class <? extends V > castSuptype = (Class <? extends V >) subtype ;
97
- final SubGraphImplementor <? extends V > result = makeSubGraph ().addTreatedSubgraph ( castSuptype );
98
- //noinspection unchecked
99
- return (SubGraphImplementor <S >) result ;
121
+ return keySubgraph ;
100
122
}
101
123
102
- @ Override
103
- public <S > SubGraphImplementor <S > makeSubGraph (ManagedType <S > subtype ) {
104
- final ManagedDomainType <V > managedType = asManagedType ( valueGraphType );
105
- final Class <S > javaType = subtype .getJavaType ();
106
- if ( !managedType .getBindableJavaType ().isAssignableFrom ( javaType ) ) {
107
- throw new IllegalArgumentException ( "Not a subtype: " + javaType .getName () );
124
+ private void checkToOne () {
125
+ final Attribute .PersistentAttributeType attributeType = attribute .getPersistentAttributeType ();
126
+ if ( attributeType != MANY_TO_ONE && attributeType != ONE_TO_ONE && attributeType != EMBEDDED ) {
127
+ throw new CannotContainSubGraphException ( "Attribute '" + attribute .getName () + "' is not a to-one association" );
128
+ }
129
+ }
130
+
131
+ private void checkToMany () {
132
+ final Attribute .PersistentAttributeType attributeType = attribute .getPersistentAttributeType ();
133
+ if ( attributeType != MANY_TO_MANY && attributeType != ONE_TO_MANY ) {
134
+ throw new CannotContainSubGraphException ( "Attribute '" + attribute .getName () + "' is not a to-many association" );
135
+ }
136
+ }
137
+
138
+ @ Override @ Deprecated
139
+ public SubGraphImplementor <E > makeSubGraph () {
140
+ verifyMutability ();
141
+ if ( valueSubgraph == null ) {
142
+ valueSubgraph = new SubGraphImpl <>( asManagedType ( valueGraphType ), true );
143
+ }
144
+ return valueSubgraph ;
145
+ }
146
+
147
+ @ Override @ Deprecated
148
+ public <S > SubGraphImplementor <S > makeSubGraph (Class <S > subtype ) {
149
+ final ManagedDomainType <E > managedType = asManagedType ( valueGraphType );
150
+ if ( !managedType .getBindableJavaType ().isAssignableFrom ( subtype ) ) {
151
+ throw new IllegalArgumentException ( "Not a subtype: " + subtype .getName () );
108
152
}
109
153
@ SuppressWarnings ("unchecked" )
110
- final ManagedDomainType <? extends V > castType = (ManagedDomainType <? extends V >) subtype ;
111
- final SubGraphImplementor <? extends V > result = makeSubGraph ().addTreatedSubgraph ( castType );
154
+ final Class <? extends E > castSuptype = (Class <? extends E >) subtype ;
155
+ final SubGraphImplementor <? extends E > result = makeSubGraph ().addTreatedSubgraph ( castSuptype );
112
156
//noinspection unchecked
113
157
return (SubGraphImplementor <S >) result ;
114
158
}
115
159
116
- @ Override
160
+ @ Override @ Deprecated
117
161
public SubGraphImplementor <K > makeKeySubGraph () {
118
162
verifyMutability ();
119
163
checkMap ();
@@ -123,7 +167,7 @@ public SubGraphImplementor<K> makeKeySubGraph() {
123
167
return keySubgraph ;
124
168
}
125
169
126
- @ Override
170
+ @ Override @ Deprecated
127
171
public <S > SubGraphImplementor <S > makeKeySubGraph (Class <S > subtype ) {
128
172
checkMap ();
129
173
final ManagedDomainType <K > type = asManagedType ( keyGraphType );
@@ -137,21 +181,6 @@ public <S> SubGraphImplementor<S> makeKeySubGraph(Class<S> subtype) {
137
181
return (SubGraphImplementor <S >) result ;
138
182
}
139
183
140
- @ Override
141
- public <S > SubGraphImplementor <S > makeKeySubGraph (ManagedType <S > subtype ) {
142
- checkMap ();
143
- final ManagedDomainType <K > type = asManagedType ( keyGraphType );
144
- final Class <S > javaType = subtype .getJavaType ();
145
- if ( !type .getBindableJavaType ().isAssignableFrom ( javaType ) ) {
146
- throw new IllegalArgumentException ( "Not a key subtype: " + javaType .getName () );
147
- }
148
- @ SuppressWarnings ("unchecked" )
149
- final ManagedDomainType <? extends K > castType = (ManagedDomainType <? extends K >) subtype ;
150
- final SubGraphImplementor <? extends K > result = makeKeySubGraph ().addTreatedSubgraph ( castType );
151
- //noinspection unchecked
152
- return (SubGraphImplementor <S >) result ;
153
- }
154
-
155
184
private void checkMap () {
156
185
if ( keyGraphType == null ) {
157
186
throw new CannotContainSubGraphException ( "Attribute '" + description () + "' is not a Map" );
@@ -179,16 +208,16 @@ public String toString() {
179
208
}
180
209
181
210
@ Override
182
- public AttributeNodeImplementor <J > makeCopy (boolean mutable ) {
211
+ public AttributeNodeImplementor <J , E , K > makeCopy (boolean mutable ) {
183
212
return !mutable && !isMutable () ? this : new AttributeNodeImpl <>( this , mutable );
184
213
}
185
214
186
215
@ Override
187
- public void merge (AttributeNodeImplementor <J > other ) {
216
+ public void merge (AttributeNodeImplementor <J , E , K > other ) {
188
217
assert other .isMutable () == isMutable ();
189
218
assert other .getAttributeDescriptor () == attribute ;
190
- final AttributeNodeImpl <J , V , K > that = (AttributeNodeImpl <J , V , K >) other ;
191
- final SubGraphImplementor <V > otherValueSubgraph = that .valueSubgraph ;
219
+ final AttributeNodeImpl <J , E , K > that = (AttributeNodeImpl <J , E , K >) other ;
220
+ final SubGraphImplementor <E > otherValueSubgraph = that .valueSubgraph ;
192
221
if ( otherValueSubgraph != null ) {
193
222
if ( valueSubgraph == null ) {
194
223
valueSubgraph = otherValueSubgraph .makeCopy ( isMutable () );
@@ -216,7 +245,7 @@ public Map<Class<?>, SubGraphImplementor<?>> getSubGraphs() {
216
245
return emptyMap ();
217
246
}
218
247
else {
219
- final HashMap <Class <?>, SubGraphImplementor <?>> map = new HashMap <>( valueSubgraph .getSubGraphs () );
248
+ final HashMap <Class <?>, SubGraphImplementor <?>> map = new HashMap <>( valueSubgraph .getTreatedSubgraphs () );
220
249
map .put ( attribute .getValueGraphType ().getBindableJavaType (), valueSubgraph );
221
250
return map ;
222
251
}
@@ -228,7 +257,7 @@ public Map<Class<?>, SubGraphImplementor<?>> getKeySubGraphs() {
228
257
return emptyMap ();
229
258
}
230
259
else {
231
- final HashMap <Class <?>, SubGraphImplementor <?>> map = new HashMap <>( keySubgraph .getSubGraphs () );
260
+ final HashMap <Class <?>, SubGraphImplementor <?>> map = new HashMap <>( keySubgraph .getTreatedSubgraphs () );
232
261
map .put ( attribute .getKeyGraphType ().getJavaType (), keySubgraph );
233
262
return map ;
234
263
}
0 commit comments