DATAMONGO-2026 - Fix id property resolution for immutable objects.

We now make sure id properties used as persistence constructor arguments are no longer set via the property accessor, but during object instantiation. Previous to this change this caused an UnsupportedOperationException.

Original pull request: #586.
This commit is contained in:
Christoph Strobl
2018-07-13 10:17:05 +02:00
committed by Oliver Gierke
parent 98433250c8
commit 390b00d5fe
2 changed files with 25 additions and 3 deletions

View File

@@ -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);

View File

@@ -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> {
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;
}
}