From 110877eb046a24ff6363f93785ff1a4cd5d00722 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 22 May 2023 10:36:53 +0200 Subject: [PATCH] Fix converter registration when using driver native time codec. This commit prevents converters from being used as writing converter causing asymmetric write/read operations. Closes #4390 Original pull request: #4392 --- .../core/convert/MongoCustomConversions.java | 4 +++ .../data/mongodb/core/MongoTemplateTests.java | 26 +++++++++++++++++++ .../MongoCustomConversionsUnitTests.java | 10 +++++++ 3 files changed, 40 insertions(+) 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 a0c1cbccb..3b38d99b6 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 @@ -41,6 +41,7 @@ import org.springframework.data.convert.PropertyValueConversions; import org.springframework.data.convert.PropertyValueConverter; import org.springframework.data.convert.PropertyValueConverterFactory; import org.springframework.data.convert.PropertyValueConverterRegistrar; +import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.SimplePropertyValueConversions; import org.springframework.data.convert.WritingConverter; import org.springframework.data.mapping.model.SimpleTypeHolder; @@ -361,6 +362,7 @@ public class MongoCustomConversions extends org.springframework.data.convert.Cus }, this.propertyValueConversions); } + @ReadingConverter private enum DateToUtcLocalDateTimeConverter implements Converter { INSTANCE; @@ -370,6 +372,7 @@ public class MongoCustomConversions extends org.springframework.data.convert.Cus } } + @ReadingConverter private enum DateToUtcLocalTimeConverter implements Converter { INSTANCE; @@ -379,6 +382,7 @@ public class MongoCustomConversions extends org.springframework.data.convert.Cus } } + @ReadingConverter private enum DateToUtcLocalDateConverter implements Converter { INSTANCE; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 9bfbe989b..ad29381e7 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -69,6 +69,8 @@ import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.BulkOperations.BulkMode; import org.springframework.data.mongodb.core.aggregation.StringOperators; import org.springframework.data.mongodb.core.convert.LazyLoadingProxy; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions; +import org.springframework.data.mongodb.core.convert.MongoCustomConversions.MongoConverterConfigurationAdapter; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.index.Index; import org.springframework.data.mongodb.core.index.IndexField; @@ -1789,6 +1791,30 @@ public class MongoTemplateTests { assertThat(result.get(0).date).isNotNull(); } + @Test // GH-4390 + void nativeDriverDateTimeCodecShouldBeApplied/*when configured*/() { + + MongoTestTemplate ops = new MongoTestTemplate(cfg -> { + cfg.configureConversion(conversion -> { + conversion.customConversions( + MongoCustomConversions.create(MongoConverterConfigurationAdapter::useNativeDriverJavaTimeCodecs)); + }); + }); + + TypeWithDate source = new TypeWithDate(); + source.id = "id-1"; + source.date = Date.from(Instant.now()); + + ops.save(source); + + var dbDate = ops.execute(TypeWithDate.class, + collection -> collection.find(new org.bson.Document("_id", source.id)).first().get("date")); + + TypeWithDate target = ops.findOne(query(where("date").is(source.date)), TypeWithDate.class); + + assertThat(target.date).isEqualTo(source.date).isEqualTo(dbDate); + } + @Test // DATAMONGO-540 public void findOneAfterUpsertForNonExistingObjectReturnsTheInsertedObject() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoCustomConversionsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoCustomConversionsUnitTests.java index 84924f354..ca13bc791 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoCustomConversionsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MongoCustomConversionsUnitTests.java @@ -64,6 +64,16 @@ class MongoCustomConversionsUnitTests { assertThat(conversions.getPropertyValueConversions().hasValueConverter(persistentProperty)).isTrue(); } + @Test // GH-4390 + void doesNotReturnConverterForNativeTimeTimeIfUsingDriverCodec() { + + MongoCustomConversions conversions = MongoCustomConversions.create(config -> { + config.useNativeDriverJavaTimeCodecs(); + }); + + assertThat(conversions.getCustomWriteTarget(Date.class)).isEmpty(); + } + static class DateToZonedDateTimeConverter implements Converter { @Override