From 531d3ac096d7755cf2617aa7b3710b67be3e74fb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 1 Sep 2023 12:01:42 +0200 Subject: [PATCH] Correctly read unwrapped properties during constructor creation. Closes: #4491 Original Pull Request: #4492 --- .../core/convert/MappingMongoConverter.java | 13 ++++++-- .../MappingMongoConverterUnitTests.java | 30 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index b3c4331d6..1e5769735 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -1963,6 +1963,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @SuppressWarnings("unchecked") public T getPropertyValue(MongoPersistentProperty property) { + ConversionContext propertyContext = context.forProperty(property); + if (property.isDbReference() && property.getDBRef().lazy()) { Object rawRefValue = accessor.get(property); @@ -1979,9 +1981,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } if (property.isDocumentReference()) { + return (T) dbRefResolver.resolveReference(property, - new DocumentReferenceSource(accessor.getDocument(), accessor.get(property)), - referenceLookupDelegate, context::convert); + new DocumentReferenceSource(accessor.getDocument(), accessor.get(property)), referenceLookupDelegate, + context::convert); + } + + if (property.isUnwrapped()) { + + return (T) readUnwrapped(propertyContext, accessor, property, + mappingContext.getRequiredPersistentEntity(property)); } return super.getPropertyValue(property); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index e9b3af915..61eb7fc1e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -2350,6 +2350,24 @@ class MappingMongoConverterUnitTests { .isEqualTo(expected); } + @Test // GH-4491 + void readUnwrappedTypeWithComplexValueUsingConstructor() { + + org.bson.Document source = new org.bson.Document("_id", "id-1").append("stringValue", "hello").append("address", + new org.bson.Document("s", "1007 Mountain Drive").append("city", "Gotham")); + + WithUnwrappedConstructor target = converter.read(WithUnwrappedConstructor.class, source); + + Address expected = new Address(); + expected.city = "Gotham"; + expected.street = "1007 Mountain Drive"; + + assertThat(target.embeddableValue.stringValue) // + .isEqualTo("hello"); + assertThat(target.embeddableValue.address) // + .isEqualTo(expected); + } + @Test // DATAMONGO-1902 void writeUnwrappedTypeWithComplexValue() { @@ -3374,6 +3392,18 @@ class MappingMongoConverterUnitTests { @Unwrapped.Nullable EmbeddableType embeddableValue; } + static class WithUnwrappedConstructor { + + private final String id; + + private final @Unwrapped.Empty EmbeddableType embeddableValue; + + public WithUnwrappedConstructor(String id, EmbeddableType embeddableValue) { + this.id = id; + this.embeddableValue = embeddableValue; + } + } + static class WithPrefixedNullableUnwrapped { String id;