30
30
import java .util .Locale ;
31
31
import java .util .Set ;
32
32
import java .util .function .Consumer ;
33
+ import java .util .function .Predicate ;
33
34
34
35
import org .apache .commons .logging .Log ;
35
36
import org .apache .commons .logging .LogFactory ;
36
37
import org .jspecify .annotations .Nullable ;
38
+
37
39
import org .springframework .core .convert .TypeDescriptor ;
38
40
import org .springframework .core .convert .converter .Converter ;
39
41
import org .springframework .core .convert .converter .ConverterFactory ;
42
+ import org .springframework .core .convert .converter .ConverterRegistry ;
40
43
import org .springframework .core .convert .converter .GenericConverter ;
41
44
import org .springframework .data .convert .ConverterBuilder ;
42
45
import org .springframework .data .convert .PropertyValueConversions ;
@@ -78,6 +81,12 @@ public class MongoCustomConversions extends org.springframework.data.convert.Cus
78
81
STORE_CONVERTERS = Collections .unmodifiableList (converters );
79
82
}
80
83
84
+ /**
85
+ * Converters to be registered with the {@code ConversionService} but hidden from CustomConversions to avoid
86
+ * converter-based type hinting.
87
+ */
88
+ private final List <Converter <?, ?>> fallbackConversionServiceConverters = new ArrayList <>();
89
+
81
90
/**
82
91
* Creates an empty {@link MongoCustomConversions} object.
83
92
*/
@@ -101,7 +110,12 @@ public MongoCustomConversions(List<?> converters) {
101
110
* @since 2.3
102
111
*/
103
112
protected MongoCustomConversions (MongoConverterConfigurationAdapter conversionConfiguration ) {
104
- super (conversionConfiguration .createConverterConfiguration ());
113
+ this (conversionConfiguration .createConverterConfiguration ());
114
+ }
115
+
116
+ private MongoCustomConversions (MongoConverterConfiguration converterConfiguration ) {
117
+ super (converterConfiguration );
118
+ this .fallbackConversionServiceConverters .addAll (converterConfiguration .fallbackConversionServiceConverters );
105
119
}
106
120
107
121
/**
@@ -120,6 +134,12 @@ public static MongoCustomConversions create(Consumer<MongoConverterConfiguration
120
134
return new MongoCustomConversions (adapter );
121
135
}
122
136
137
+ @ Override
138
+ public void registerConvertersIn (ConverterRegistry conversionService ) {
139
+ this .fallbackConversionServiceConverters .forEach (conversionService ::addConverter );
140
+ super .registerConvertersIn (conversionService );
141
+ }
142
+
123
143
@ WritingConverter
124
144
private enum CustomToStringConverter implements GenericConverter {
125
145
@@ -155,7 +175,7 @@ public static class MongoConverterConfigurationAdapter {
155
175
LocalDateTime .class );
156
176
157
177
private boolean useNativeDriverJavaTimeCodecs = false ;
158
- private BigDecimalRepresentation @ Nullable [] bigDecimals ;
178
+ private @ Nullable BigDecimalRepresentation bigDecimals ;
159
179
private final List <Object > customConverters = new ArrayList <>();
160
180
161
181
private final PropertyValueConversions internalValueConversion = PropertyValueConversions .simple (it -> {});
@@ -312,14 +332,14 @@ public MongoConverterConfigurationAdapter useSpringDataJavaTimeCodecs() {
312
332
* Configures the representation to for {@link java.math.BigDecimal} and {@link java.math.BigInteger} values in
313
333
* MongoDB. Defaults to {@link BigDecimalRepresentation#DECIMAL128}.
314
334
*
315
- * @param representations ordered list of representations to use (first one is default)
335
+ * @param representation the representation to use.
316
336
* @return this.
317
337
* @since 4.5
318
338
*/
319
- public MongoConverterConfigurationAdapter bigDecimal (BigDecimalRepresentation ... representations ) {
339
+ public MongoConverterConfigurationAdapter bigDecimal (BigDecimalRepresentation representation ) {
320
340
321
- Assert .notEmpty ( representations , "BigDecimalDataType must not be null" );
322
- this .bigDecimals = representations ;
341
+ Assert .notNull ( representation , "BigDecimalDataType must not be null" );
342
+ this .bigDecimals = representation ;
323
343
return this ;
324
344
}
325
345
@@ -365,27 +385,32 @@ PropertyValueConversions valueConversions() {
365
385
return this .propertyValueConversions ;
366
386
}
367
387
368
- ConverterConfiguration createConverterConfiguration () {
388
+ MongoConverterConfiguration createConverterConfiguration () {
369
389
370
390
if (hasDefaultPropertyValueConversions ()
371
391
&& propertyValueConversions instanceof SimplePropertyValueConversions svc ) {
372
392
svc .init ();
373
393
}
374
394
375
395
List <Object > storeConverters = new ArrayList <>(STORE_CONVERTERS .size () + 10 );
376
-
377
- if (bigDecimals != null ) {
378
- for (BigDecimalRepresentation representation : bigDecimals ) {
379
- switch (representation ) {
380
- case STRING -> storeConverters .addAll (MongoConverters .getBigNumberStringConverters ());
381
- case DECIMAL128 -> storeConverters .addAll (MongoConverters .getBigNumberDecimal128Converters ());
382
- }
396
+ List <Converter <?, ?>> fallbackConversionServiceConverters = new ArrayList <>(5 );
397
+ fallbackConversionServiceConverters .addAll (MongoConverters .getBigNumberStringConverters ());
398
+ fallbackConversionServiceConverters .addAll (MongoConverters .getBigNumberDecimal128Converters ());
399
+
400
+ if (bigDecimals == null ) {
401
+ if (LOGGER .isInfoEnabled ()) {
402
+ LOGGER .info (
403
+ "No BigDecimal/BigInteger representation set. Choose 'BigDecimalRepresentation.DECIMAL128' or 'BigDecimalRepresentation.String' to store values in desired format." );
404
+ }
405
+ } else {
406
+ switch (bigDecimals ) {
407
+ case STRING -> storeConverters .addAll (MongoConverters .getBigNumberStringConverters ());
408
+ case DECIMAL128 -> storeConverters .addAll (MongoConverters .getBigNumberDecimal128Converters ());
383
409
}
384
- } else if (LOGGER .isInfoEnabled ()) {
385
- LOGGER .info (
386
- "No BigDecimal/BigInteger representation set. Choose [DECIMAL128] and/or [String] to store values in desired format." );
387
410
}
388
411
412
+ fallbackConversionServiceConverters .removeAll (storeConverters );
413
+
389
414
if (useNativeDriverJavaTimeCodecs ) {
390
415
391
416
/*
@@ -397,7 +422,8 @@ ConverterConfiguration createConverterConfiguration() {
397
422
StoreConversions storeConversions = StoreConversions
398
423
.of (new SimpleTypeHolder (JAVA_DRIVER_TIME_SIMPLE_TYPES , MongoSimpleTypes .HOLDER ), storeConverters );
399
424
400
- return new ConverterConfiguration (storeConversions , this .customConverters , convertiblePair -> {
425
+ return new MongoConverterConfiguration (storeConversions , fallbackConversionServiceConverters ,
426
+ this .customConverters , convertiblePair -> {
401
427
402
428
// Avoid default registrations
403
429
@@ -408,8 +434,10 @@ ConverterConfiguration createConverterConfiguration() {
408
434
}
409
435
410
436
storeConverters .addAll (STORE_CONVERTERS );
411
- return new ConverterConfiguration (StoreConversions .of (MongoSimpleTypes .createSimpleTypeHolder (), storeConverters ),
412
- this .customConverters , convertiblePair -> true , this .propertyValueConversions );
437
+ return new MongoConverterConfiguration (
438
+ StoreConversions .of (MongoSimpleTypes .createSimpleTypeHolder (), storeConverters ),
439
+ fallbackConversionServiceConverters , this .customConverters , convertiblePair -> true ,
440
+ this .propertyValueConversions );
413
441
}
414
442
415
443
private boolean hasDefaultPropertyValueConversions () {
@@ -418,6 +446,19 @@ private boolean hasDefaultPropertyValueConversions() {
418
446
419
447
}
420
448
449
+ static class MongoConverterConfiguration extends ConverterConfiguration {
450
+
451
+ private final List <Converter <?, ?>> fallbackConversionServiceConverters ;
452
+
453
+ public MongoConverterConfiguration (StoreConversions storeConversions ,
454
+ List <Converter <?, ?>> fallbackConversionServiceConverters , List <?> userConverters ,
455
+ Predicate <GenericConverter .ConvertiblePair > converterRegistrationFilter ,
456
+ @ Nullable PropertyValueConversions propertyValueConversions ) {
457
+ super (storeConversions , userConverters , converterRegistrationFilter , propertyValueConversions );
458
+ this .fallbackConversionServiceConverters = fallbackConversionServiceConverters ;
459
+ }
460
+ }
461
+
421
462
/**
422
463
* Strategy to represent {@link java.math.BigDecimal} and {@link java.math.BigInteger} values in MongoDB.
423
464
*
0 commit comments