Skip to content

Commit 5c82b15

Browse files
committed
Require explicit BigDecimal representation configuration
Signed-off-by: Hyunsang Han <[email protected]>
1 parent 13b89db commit 5c82b15

File tree

3 files changed

+88
-8
lines changed

3 files changed

+88
-8
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
*
6262
* @author Mark Paluch
6363
* @author Christoph Strobl
64+
* @author Hyunsang Han
6465
* @since 2.0
6566
* @see org.springframework.data.convert.CustomConversions
6667
* @see org.springframework.data.mapping.model.SimpleTypeHolder
@@ -159,7 +160,7 @@ public static class MongoConverterConfigurationAdapter {
159160
private static final Set<Class<?>> JAVA_DRIVER_TIME_SIMPLE_TYPES = Set.of(LocalDate.class, LocalTime.class, LocalDateTime.class);
160161

161162
private boolean useNativeDriverJavaTimeCodecs = false;
162-
private BigDecimalRepresentation bigDecimals = BigDecimalRepresentation.DECIMAL128;
163+
private @Nullable BigDecimalRepresentation bigDecimals;
163164
private final List<Object> customConverters = new ArrayList<>();
164165

165166
private final PropertyValueConversions internalValueConversion = PropertyValueConversions.simple(it -> {});
@@ -313,8 +314,8 @@ public MongoConverterConfigurationAdapter useSpringDataJavaTimeCodecs() {
313314
}
314315

315316
/**
316-
* Configures the representation to for {@link java.math.BigDecimal} and {@link java.math.BigInteger} values in
317-
* MongoDB. Defaults to {@link BigDecimalRepresentation#DECIMAL128}.
317+
* Configures the representation for {@link java.math.BigDecimal} and {@link java.math.BigInteger} values in
318+
* MongoDB. This configuration is required and must be explicitly set.
318319
*
319320
* @param representation the representation to use.
320321
* @return this.
@@ -375,6 +376,10 @@ ConverterConfiguration createConverterConfiguration() {
375376
svc.init();
376377
}
377378

379+
if (bigDecimals == null) {
380+
throw new IllegalStateException("BigDecimal representation must be explicitly configured.");
381+
}
382+
378383
List<Object> converters = new ArrayList<>(STORE_CONVERTERS.size() + 7);
379384

380385
if (bigDecimals == BigDecimalRepresentation.STRING) {

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
* @author Roman Puchkovskiy
124124
* @author Heesu Jung
125125
* @author Julia Lee
126+
* @author Hyunsang Han
126127
*/
127128
@ExtendWith(MockitoExtension.class)
128129
class MappingMongoConverterUnitTests {
@@ -135,8 +136,10 @@ class MappingMongoConverterUnitTests {
135136
@BeforeEach
136137
void beforeEach() {
137138

138-
MongoCustomConversions conversions = new MongoCustomConversions(
139-
Arrays.asList(new ByteBufferToDoubleHolderConverter()));
139+
MongoCustomConversions conversions = MongoCustomConversions.create(config -> {
140+
config.bigDecimal(MongoCustomConversions.BigDecimalRepresentation.DECIMAL128);
141+
config.registerConverter(new ByteBufferToDoubleHolderConverter());
142+
});
140143

141144
mappingContext = new MongoMappingContext();
142145
mappingContext.setApplicationContext(context);
@@ -414,6 +417,30 @@ void readsClassWithBigDecimal() {
414417
assertThat(result.collection.get(0)).isEqualTo(BigDecimal.valueOf(2.5d));
415418
}
416419

420+
@Test // GH-5037
421+
void requiresExplicitBigDecimalRepresentationConfiguration() {
422+
423+
assertThatThrownBy(() -> {
424+
MongoCustomConversions customConversions = new MongoCustomConversions(Collections.emptyList());
425+
MappingMongoConverter converter = new MappingMongoConverter(mock(DbRefResolver.class), mappingContext);
426+
converter.setCustomConversions(customConversions);
427+
}).isInstanceOf(IllegalStateException.class)
428+
.hasMessageContaining("BigDecimal representation must be explicitly configured");
429+
}
430+
431+
@Test // GH-5037
432+
void worksWithExplicitBigDecimalRepresentationConfiguration() {
433+
434+
MongoCustomConversions customConversions = MongoCustomConversions.create(config -> {
435+
config.bigDecimal(MongoCustomConversions.BigDecimalRepresentation.DECIMAL128);
436+
});
437+
438+
MappingMongoConverter converter = new MappingMongoConverter(mock(DbRefResolver.class), mappingContext);
439+
converter.setCustomConversions(customConversions);
440+
assertThat(converter).isNotNull();
441+
assertThat(converter.getCustomConversions()).isEqualTo(customConversions);
442+
}
443+
417444
@Test
418445
void writesNestedCollectionsCorrectly() {
419446

@@ -3407,6 +3434,26 @@ void usesStringNumericFormat() {
34073434
assertThat(document).containsEntry("map.foo", "2.5");
34083435
}
34093436

3437+
@Test // GH-5037
3438+
void requiresExplicitConfigurationForBothBigDecimalAndUuid() {
3439+
3440+
MongoCustomConversions conversions = MongoCustomConversions.create(
3441+
it -> it.registerConverter(new ByteBufferToDoubleHolderConverter())
3442+
.bigDecimal(MongoCustomConversions.BigDecimalRepresentation.DECIMAL128));
3443+
3444+
assertThat(conversions).isNotNull();
3445+
3446+
assertThatThrownBy(() -> {
3447+
new MongoCustomConversions();
3448+
}).isInstanceOf(IllegalStateException.class)
3449+
.hasMessageContaining("BigDecimal representation must be explicitly configured");
3450+
3451+
assertThatThrownBy(() -> {
3452+
MongoCustomConversions.create(it -> it.registerConverter(new ByteBufferToDoubleHolderConverter()));
3453+
}).isInstanceOf(IllegalStateException.class)
3454+
.hasMessageContaining("BigDecimal representation must be explicitly configured");
3455+
}
3456+
34103457
private MappingMongoConverter createConverter(
34113458
MongoCustomConversions.BigDecimalRepresentation bigDecimalRepresentation) {
34123459

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoCustomConversionsUnitTests.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,24 @@
2727
import org.springframework.data.convert.PropertyValueConverter;
2828
import org.springframework.data.mapping.PersistentEntity;
2929
import org.springframework.data.mapping.PersistentProperty;
30+
import org.springframework.data.mongodb.core.convert.MongoCustomConversions.BigDecimalRepresentation;
3031
import org.springframework.data.mongodb.core.convert.QueryMapperUnitTests.Foo;
3132

3233
/**
3334
* Unit tests for {@link MongoCustomConversions}.
3435
*
3536
* @author Christoph Strobl
37+
* @author Hyunsang Han
3638
*/
3739
class MongoCustomConversionsUnitTests {
3840

3941
@Test // DATAMONGO-2349
4042
void nonAnnotatedConverterForJavaTimeTypeShouldOnlyBeRegisteredAsReadingConverter() {
4143

42-
MongoCustomConversions conversions = new MongoCustomConversions(
43-
Collections.singletonList(new DateToZonedDateTimeConverter()));
44+
MongoCustomConversions conversions = MongoCustomConversions.create(config -> {
45+
config.bigDecimal(BigDecimalRepresentation.DECIMAL128);
46+
config.registerConverter(new DateToZonedDateTimeConverter());
47+
});
4448

4549
assertThat(conversions.hasCustomReadTarget(Date.class, ZonedDateTime.class)).isTrue();
4650
assertThat(conversions.hasCustomWriteTarget(Date.class)).isFalse();
@@ -56,7 +60,7 @@ void propertyValueConverterRegistrationWorksAsExpected() {
5660
when(owner.getType()).thenReturn(Foo.class);
5761

5862
MongoCustomConversions conversions = MongoCustomConversions.create(config -> {
59-
63+
config.bigDecimal(BigDecimalRepresentation.DECIMAL128);
6064
config.configurePropertyConversions(
6165
registry -> registry.registerConverter(Foo.class, "name", mock(PropertyValueConverter.class)));
6266
});
@@ -68,12 +72,36 @@ void propertyValueConverterRegistrationWorksAsExpected() {
6872
void doesNotReturnConverterForNativeTimeTimeIfUsingDriverCodec() {
6973

7074
MongoCustomConversions conversions = MongoCustomConversions.create(config -> {
75+
config.bigDecimal(BigDecimalRepresentation.DECIMAL128);
7176
config.useNativeDriverJavaTimeCodecs();
7277
});
7378

7479
assertThat(conversions.getCustomWriteTarget(Date.class)).isEmpty();
7580
}
7681

82+
@Test // GH-5037
83+
void requiresExplicitBigDecimalRepresentationConfiguration() {
84+
85+
assertThatThrownBy(() -> {
86+
MongoCustomConversions.create(config -> {
87+
config.useSpringDataJavaTimeCodecs();
88+
});
89+
}).isInstanceOf(IllegalStateException.class)
90+
.hasMessageContaining("BigDecimal representation must be explicitly configured");
91+
}
92+
93+
@Test // GH-5037
94+
void worksWithExplicitBigDecimalRepresentationConfiguration() {
95+
96+
MongoCustomConversions conversions = MongoCustomConversions.create(config -> {
97+
config.bigDecimal(BigDecimalRepresentation.DECIMAL128);
98+
config.useSpringDataJavaTimeCodecs();
99+
});
100+
101+
assertThat(conversions).isNotNull();
102+
assertThat(conversions.getSimpleTypeHolder()).isNotNull();
103+
}
104+
77105
static class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
78106

79107
@Override

0 commit comments

Comments
 (0)