20
20
import static com .mongodb .hibernate .internal .MongoAssertions .assertNotNull ;
21
21
import static com .mongodb .hibernate .internal .MongoAssertions .assertTrue ;
22
22
import static com .mongodb .hibernate .internal .MongoAssertions .fail ;
23
+ import static com .mongodb .hibernate .internal .type .ValueConversions .toArrayDomainValue ;
23
24
import static com .mongodb .hibernate .internal .type .ValueConversions .toBsonValue ;
24
25
import static com .mongodb .hibernate .internal .type .ValueConversions .toDomainValue ;
25
26
26
27
import com .mongodb .hibernate .internal .FeatureNotSupportedException ;
27
28
import java .io .Serial ;
29
+ import java .lang .reflect .ParameterizedType ;
28
30
import java .sql .CallableStatement ;
29
31
import java .sql .JDBCType ;
30
32
import java .sql .PreparedStatement ;
31
33
import java .sql .ResultSet ;
32
34
import java .sql .SQLException ;
33
35
import java .sql .SQLFeatureNotSupportedException ;
36
+ import java .util .Collection ;
34
37
import org .bson .BsonDocument ;
35
38
import org .bson .BsonValue ;
36
39
import org .hibernate .annotations .Struct ;
@@ -91,10 +94,8 @@ public EmbeddableMappingType getEmbeddableMappingType() {
91
94
92
95
@ Override
93
96
public BsonDocument createJdbcValue (Object domainValue , WrapperOptions options ) throws SQLException {
94
- var embeddableMappingType = assertNotNull (this .embeddableMappingType );
95
- if (embeddableMappingType .isPolymorphic ()) {
96
- throw new FeatureNotSupportedException ("Polymorphic mapping is not supported" );
97
- }
97
+ var embeddableMappingType = getEmbeddableMappingType ();
98
+ forbidPolymorphic (embeddableMappingType );
98
99
var result = new BsonDocument ();
99
100
var jdbcValueCount = embeddableMappingType .getJdbcValueCount ();
100
101
for (int columnIndex = 0 ; columnIndex < jdbcValueCount ; columnIndex ++) {
@@ -134,21 +135,65 @@ public BsonDocument createJdbcValue(Object domainValue, WrapperOptions options)
134
135
135
136
@ Override
136
137
public Object [] extractJdbcValues (Object rawJdbcValue , WrapperOptions options ) throws SQLException {
138
+ var embeddableMappingType = getEmbeddableMappingType ();
139
+ forbidPolymorphic (embeddableMappingType );
137
140
if (!(rawJdbcValue instanceof BsonDocument bsonDocument )) {
138
141
throw fail ();
139
142
}
140
143
var result = new Object [bsonDocument .size ()];
141
144
var elementIdx = 0 ;
142
145
for (var value : bsonDocument .values ()) {
143
146
assertNotNull (value );
144
- result [elementIdx ++] =
145
- value instanceof BsonDocument ? extractJdbcValues (value , options ) : toDomainValue (value );
147
+ var jdbcMapping =
148
+ embeddableMappingType .getJdbcValueSelectable (elementIdx ).getJdbcMapping ();
149
+ var mappedJavaType = jdbcMapping .getMappedJavaType ();
150
+ var mappedJavaTypeClass = mappedJavaType .getJavaTypeClass ();
151
+ Object domainValue ;
152
+ if (jdbcMapping .getJdbcType ().getJdbcTypeCode () == JDBC_TYPE .getVendorTypeNumber ()) {
153
+ if (!(jdbcMapping .getJdbcValueExtractor () instanceof Extractor <?> structValueExtractor )) {
154
+ throw fail ();
155
+ }
156
+ if (!(structValueExtractor .getJdbcType () instanceof MongoStructJdbcType structJdbcType )) {
157
+ throw fail ();
158
+ }
159
+ domainValue = structJdbcType .extractJdbcValues (value , options );
160
+ } else if (mappedJavaTypeClass .equals (byte [].class )) {
161
+ domainValue = toDomainValue (value , mappedJavaTypeClass );
162
+ } else if (mappedJavaTypeClass .equals (char [].class )) {
163
+ // VAKOTODO replace toArrayDomainValue with toDomainValue that accepts nullable arrayContentsType?
164
+ // this is to avoid checking for char[].class outside of ValueConversions
165
+ domainValue =
166
+ toArrayDomainValue (value , mappedJavaTypeClass , null ).getArray ();
167
+ } else if (mappedJavaTypeClass .isArray ()) {
168
+ domainValue =
169
+ toArrayDomainValue (value , mappedJavaTypeClass , null ).getArray ();
170
+ } else if (Collection .class .isAssignableFrom (mappedJavaTypeClass )) { // VAKOTODO use equals?
171
+ if (!(mappedJavaType .getJavaType () instanceof ParameterizedType parameterizedCollection )) {
172
+ throw fail ();
173
+ }
174
+ var collectionTypeArguments = parameterizedCollection .getActualTypeArguments ();
175
+ assertTrue (collectionTypeArguments .length == 1 );
176
+ if (!(collectionTypeArguments [0 ] instanceof Class <?> collectionTypeArgument )) {
177
+ throw fail ();
178
+ }
179
+ domainValue = toArrayDomainValue (value , mappedJavaTypeClass , collectionTypeArgument )
180
+ .getArray ();
181
+ } else {
182
+ domainValue = toDomainValue (value , mappedJavaTypeClass );
183
+ }
184
+ result [elementIdx ++] = domainValue ;
146
185
}
147
186
return result ;
148
187
}
149
188
189
+ private static void forbidPolymorphic (EmbeddableMappingType embeddableMappingType ) {
190
+ if (embeddableMappingType .isPolymorphic ()) {
191
+ throw new FeatureNotSupportedException ("Polymorphic mapping is not supported" );
192
+ }
193
+ }
194
+
150
195
@ Override
151
- public int getJdbcTypeCode () {
196
+ public int getJdbcTypeCode () { // VAKOTODO use instead of exposing JDBC_TYPE?
152
197
return JDBC_TYPE .getVendorTypeNumber ();
153
198
}
154
199
@@ -172,11 +217,16 @@ private final class Binder<X> extends BasicBinder<X> {
172
217
}
173
218
174
219
@ Override
175
- protected void doBind ( PreparedStatement st , X value , int index , WrapperOptions options ) throws SQLException {
220
+ public Object getBindValue ( X value , WrapperOptions options ) throws SQLException {
176
221
if (!(getJdbcType () instanceof MongoStructJdbcType structJdbcType )) {
177
222
throw fail ();
178
223
}
179
- st .setObject (index , structJdbcType .createJdbcValue (value , options ), structJdbcType .getJdbcTypeCode ());
224
+ return structJdbcType .createJdbcValue (value , options );
225
+ }
226
+
227
+ @ Override
228
+ protected void doBind (PreparedStatement st , X value , int index , WrapperOptions options ) throws SQLException {
229
+ st .setObject (index , getBindValue (value , options ), getJdbcType ().getJdbcTypeCode ());
180
230
}
181
231
182
232
@ Override
0 commit comments