15
15
*/
16
16
package org .springframework .data .jdbc .repository .query ;
17
17
18
+ import java .sql .JDBCType ;
18
19
import java .sql .Types ;
19
20
import java .util .ArrayList ;
20
21
import java .util .Collection ;
@@ -245,8 +246,8 @@ private Condition getCondition(CriteriaDefinition criteria, MapSqlParameterSourc
245
246
return mapCondition (criteria , parameterSource , table , entity );
246
247
}
247
248
248
- private Condition combine (@ Nullable Condition currentCondition ,
249
- CriteriaDefinition . Combinator combinator , Condition nextCondition ) {
249
+ private Condition combine (@ Nullable Condition currentCondition , CriteriaDefinition . Combinator combinator ,
250
+ Condition nextCondition ) {
250
251
251
252
if (currentCondition == null ) {
252
253
currentCondition = nextCondition ;
@@ -292,6 +293,17 @@ private Condition mapCondition(CriteriaDefinition criteria, MapSqlParameterSourc
292
293
293
294
mappedValue = convertValue (value , propertyField .getTypeHint ());
294
295
sqlType = propertyField .getSqlType ();
296
+
297
+ } else if (propertyField instanceof MetadataBackedField //
298
+ && ((MetadataBackedField ) propertyField ).property != null //
299
+ && (criteria .getValue () == null || !criteria .getValue ().getClass ().isArray ())) {
300
+
301
+ final RelationalPersistentProperty property = ((MetadataBackedField ) propertyField ).property ;
302
+ JdbcValue jdbcValue = convertSpecial (property , criteria .getValue ());
303
+ mappedValue = jdbcValue .getValue ();
304
+ sqlType = jdbcValue .getJdbcType () != null ? jdbcValue .getJdbcType ().getVendorTypeNumber ()
305
+ : propertyField .getSqlType ();
306
+
295
307
} else {
296
308
297
309
mappedValue = convertValue (criteria .getValue (), propertyField .getTypeHint ());
@@ -302,6 +314,84 @@ private Condition mapCondition(CriteriaDefinition criteria, MapSqlParameterSourc
302
314
criteria .isIgnoreCase ());
303
315
}
304
316
317
+ /**
318
+ * Converts values while taking special value types like arrays, {@link Iterable}, or {@link Pair}.
319
+ *
320
+ * @param property the property to which the value relates. It determines the type to convert to. Must not be
321
+ * {@literal null}.
322
+ * @param value the value to be converted.
323
+ * @return a non null {@link JdbcValue} holding the converted value and the appropriate JDBC type information.
324
+ */
325
+ private JdbcValue convertSpecial (RelationalPersistentProperty property , @ Nullable Object value ) {
326
+
327
+ if (value == null ) {
328
+ return JdbcValue .of (null , JDBCType .NULL );
329
+ }
330
+
331
+ if (value instanceof Pair ) {
332
+
333
+ final JdbcValue first = convertSimple (property , ((Pair <?, ?>) value ).getFirst ());
334
+ final JdbcValue second = convertSimple (property , ((Pair <?, ?>) value ).getSecond ());
335
+ return JdbcValue .of (Pair .of (first .getValue (), second .getValue ()), first .getJdbcType ());
336
+ }
337
+
338
+ if (value instanceof Iterable ) {
339
+
340
+ List <Object > mapped = new ArrayList <>();
341
+ JDBCType jdbcType = null ;
342
+
343
+ for (Object o : (Iterable <?>) value ) {
344
+
345
+ final JdbcValue jdbcValue = convertSimple (property , o );
346
+ if (jdbcType == null ) {
347
+ jdbcType = jdbcValue .getJdbcType ();
348
+ }
349
+
350
+ mapped .add (jdbcValue .getValue ());
351
+ }
352
+
353
+ return JdbcValue .of (mapped , jdbcType );
354
+ }
355
+
356
+ if (value .getClass ().isArray ()) {
357
+
358
+ final Object [] valueAsArray = (Object []) value ;
359
+ final Object [] mappedValueArray = new Object [valueAsArray .length ];
360
+ JDBCType jdbcType = null ;
361
+
362
+ for (int i = 0 ; i < valueAsArray .length ; i ++) {
363
+
364
+ final JdbcValue jdbcValue = convertSimple (property , valueAsArray [i ]);
365
+ if (jdbcType == null ) {
366
+ jdbcType = jdbcValue .getJdbcType ();
367
+ }
368
+
369
+ mappedValueArray [i ] = jdbcValue .getValue ();
370
+ }
371
+
372
+ return JdbcValue .of (mappedValueArray , jdbcType );
373
+ }
374
+
375
+ return convertSimple (property , value );
376
+ }
377
+
378
+ /**
379
+ * Converts values to a {@link JdbcValue}.
380
+ *
381
+ * @param property the property to which the value relates. It determines the type to convert to. Must not be
382
+ * {@literal null}.
383
+ * @param value the value to be converted.
384
+ * @return a non null {@link JdbcValue} holding the converted value and the appropriate JDBC type information.
385
+ */
386
+ private JdbcValue convertSimple (RelationalPersistentProperty property , Object value ) {
387
+
388
+ return converter .writeJdbcValue ( //
389
+ value , //
390
+ converter .getColumnType (property ), //
391
+ converter .getSqlType (property ) //
392
+ );
393
+ }
394
+
305
395
private Condition mapEmbeddedObjectCondition (CriteriaDefinition criteria , MapSqlParameterSource parameterSource ,
306
396
Table table , RelationalPersistentProperty embeddedProperty ) {
307
397
@@ -740,11 +830,6 @@ public TypeInformation<?> getTypeHint() {
740
830
return this .property .getTypeInformation ();
741
831
}
742
832
743
- if (this .property .getType ().isInterface ()
744
- || (java .lang .reflect .Modifier .isAbstract (this .property .getType ().getModifiers ()))) {
745
- return ClassTypeInformation .OBJECT ;
746
- }
747
-
748
833
return this .property .getTypeInformation ();
749
834
}
750
835
0 commit comments