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 23df7f06e..73178e96a 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 @@ -282,10 +282,15 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App // make sure id property is set before all other properties Object idValue = null; - if (idProperty != null && documentAccessor.hasValue(idProperty)) { + if (idProperty != null) { - idValue = readIdValue(path, evaluator, idProperty, documentAccessor); - accessor.setProperty(idProperty, idValue); + if (idProperty.isImmutable() && entity.isConstructorArgument(idProperty)) { + idValue = accessor.getProperty(idProperty); + } else if (documentAccessor.hasValue(idProperty)) { + + idValue = readIdValue(path, evaluator, idProperty, documentAccessor); + accessor.setProperty(idProperty, idValue); + } } ObjectPath currentPath = path.push(instance, entity, idValue != null ? bson.get(idProperty.getFieldName()) : null); 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 427d41a7d..f7890c8fa 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 @@ -1882,6 +1882,15 @@ public class MappingMongoConverterUnitTests { assertThat(result.id).isEqualTo("foo"); assertThat(result.witherUsed).isTrue(); } + @Test // DATAMONGO-2026 + public void readsImmutableObjectWithConstructorIdPropertyCorrectly() { + + org.bson.Document source = new org.bson.Document("_id", "spring").append("value", "data"); + + ImmutableObjectWithIdConstructorPropertyAndNoIdWitherMethod target = converter.read(ImmutableObjectWithIdConstructorPropertyAndNoIdWitherMethod.class, source); + assertThat(target.id).isEqualTo("spring"); + assertThat(target.value).isEqualTo("data"); + } static class GenericType { T content; @@ -2265,6 +2274,7 @@ public class MappingMongoConverterUnitTests { } static class ImmutableObject { + final String id; final String name; final boolean witherUsed; @@ -2303,4 +2313,11 @@ public class MappingMongoConverterUnitTests { return witherUsed; } } + + @RequiredArgsConstructor + static class ImmutableObjectWithIdConstructorPropertyAndNoIdWitherMethod { + + final @Id String id; + String value; + } }