diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java
index a61646783..b3c771bc4 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java
@@ -32,6 +32,7 @@ import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingSt
import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
+import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.util.ClassUtils;
@@ -92,14 +93,35 @@ public abstract class MongoConfigurationSupport {
/**
* Register custom {@link Converter}s in a {@link CustomConversions} object if required. These
- * {@link CustomConversions} will be registered with the {@link #mappingMongoConverter()} and
- * {@link #mongoMappingContext()}. Returns an empty {@link MongoCustomConversions} instance by default.
+ * {@link CustomConversions} will be registered with the
+ * {@link org.springframework.data.mongodb.core.convert.MappingMongoConverter} and {@link #mongoMappingContext()}.
+ * Returns an empty {@link MongoCustomConversions} instance by default.
+ * NOTE: Use {@link #customConversionsConfiguration(MongoConverterConfigurationAdapter)} to configure
+ * MongoDB native simple types and register custom {@link Converter converters}.
*
* @return must not be {@literal null}.
*/
@Bean
public CustomConversions customConversions() {
- return new MongoCustomConversions(Collections.emptyList());
+ return new MongoCustomConversions(this::customConversionsConfiguration);
+ }
+
+ /**
+ * Configuration hook for {@link MongoCustomConversions} creation.
+ *
+ * @param converterConfigurationAdapter never {@literal null}.
+ * @since 2.3
+ */
+ protected void customConversionsConfiguration(MongoConverterConfigurationAdapter converterConfigurationAdapter) {
+
+ /*
+ * In case you want to use the MongoDB Java Driver native Codecs for java.time types instead of the converters SpringData
+ * ships with, then you may want to call the following here.
+ *
+ * converterConfigurationAdapter.useNativeDriverJavaTimeCodecs()
+ *
+ * But please, be careful! LocalDate, LocalTime and LocalDateTime will be stored with different values by doing so.
+ */
}
/**
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java
index 7e5659045..ff9023a4f 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java
@@ -15,26 +15,42 @@
*/
package org.springframework.data.mongodb.core.convert;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter;
+import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
import org.springframework.data.convert.JodaTimeConverters;
import org.springframework.data.convert.WritingConverter;
+import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
import org.springframework.lang.Nullable;
+import org.springframework.util.Assert;
/**
* Value object to capture custom conversion. {@link MongoCustomConversions} also act as factory for
* {@link org.springframework.data.mapping.model.SimpleTypeHolder}
*
* @author Mark Paluch
+ * @author Christoph Strobl
* @since 2.0
* @see org.springframework.data.convert.CustomConversions
* @see org.springframework.data.mapping.model.SimpleTypeHolder
@@ -71,7 +87,30 @@ public class MongoCustomConversions extends org.springframework.data.convert.Cus
* @param converters must not be {@literal null}.
*/
public MongoCustomConversions(List> converters) {
- super(STORE_CONVERSIONS, converters);
+
+ this(converterConfigurationAdapter -> {
+
+ converterConfigurationAdapter.useSpringDataJavaTimeCodecs();
+ converterConfigurationAdapter.registerConverters(converters);
+ });
+ }
+
+ /**
+ * Functional style {@link org.springframework.data.convert.CustomConversions} creation giving users a convenient way
+ * of configuring store specific capabilities by providing deferred hooks to what will be configured when creating the
+ * {@link org.springframework.data.convert.CustomConversions#CustomConversions(ConverterConfiguration) instance}.
+ *
+ * @param conversionConfiguration must not be {@literal null}.
+ * @since 2.3
+ */
+ public MongoCustomConversions(Consumer conversionConfiguration) {
+
+ super(() -> {
+
+ MongoConverterConfigurationAdapter adapter = new MongoConverterConfigurationAdapter();
+ conversionConfiguration.accept(adapter);
+ return adapter.createConverterConfiguration();
+ });
}
@WritingConverter
@@ -99,4 +138,158 @@ public class MongoCustomConversions extends org.springframework.data.convert.Cus
return source != null ? source.toString() : null;
}
}
+
+ /**
+ * {@link MongoConverterConfigurationAdapter} encapsulates creation of
+ * {@link org.springframework.data.convert.CustomConversions.ConverterConfiguration} with MongoDB specifics.
+ *
+ * @author Christoph Strobl
+ * @since 2.3
+ */
+ public static class MongoConverterConfigurationAdapter {
+
+ /**
+ * List of {@literal java.time} types having different representation when rendered via the native
+ * {@link org.bson.codecs.Codec} than the Spring Data {@link Converter}.
+ */
+ private static final List> JAVA_DRIVER_TIME_SIMPLE_TYPES = Arrays.asList(LocalDate.class, LocalTime.class,
+ LocalDateTime.class);
+
+ private boolean useNativeDriverJavaTimeCodecs = false;
+ private List