DATACMNS-1322 - Add support for immutable entities in PersistentPropertyAccessor.setProperty(PersistentPropertyPath, Object).
As setting a PersistentProperty can actually change the object that the property is changed on, we now recursively traverse property paths up as longs as the setting of the property results in the bean not being replaced.
This commit is contained in:
@@ -71,9 +71,21 @@ public interface PersistentPropertyAccessor {
|
||||
getBean().getClass().getName()));
|
||||
}
|
||||
|
||||
PersistentPropertyAccessor accessor = leafProperty.getOwner().getPropertyAccessor(parent);
|
||||
PersistentPropertyAccessor accessor = parent == getBean() //
|
||||
? this //
|
||||
: leafProperty.getOwner().getPropertyAccessor(parent);
|
||||
|
||||
accessor.setProperty(leafProperty, value);
|
||||
|
||||
if (parentPath.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object bean = accessor.getBean();
|
||||
|
||||
if (bean != parent) {
|
||||
setProperty(parentPath, bean);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,12 +17,15 @@ package org.springframework.data.mapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Value;
|
||||
import lombok.experimental.Wither;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mapping.context.SampleMappingContext;
|
||||
import org.springframework.data.mapping.context.SamplePersistentProperty;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
@@ -90,6 +93,27 @@ public class PersistentPropertyAccessorUnitTests {
|
||||
.isThrownBy(() -> accessor.setProperty(path, "Oliver August"));
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1322
|
||||
public void correctlyReplacesObjectInstancesWhenSettingPropertyPathOnImmutableObjects() {
|
||||
|
||||
PersistentEntity<Object, SamplePersistentProperty> entity = context.getPersistentEntity(Outer.class);
|
||||
PersistentPropertyPath<SamplePersistentProperty> path = context.getPersistentPropertyPath("immutable.value",
|
||||
entity.getType());
|
||||
|
||||
NestedImmutable immutable = new NestedImmutable("foo");
|
||||
Outer outer = new Outer(immutable);
|
||||
|
||||
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(outer);
|
||||
accessor.setProperty(path, "bar");
|
||||
|
||||
Object result = accessor.getBean();
|
||||
|
||||
assertThat(result).isInstanceOfSatisfying(Outer.class, it -> {
|
||||
assertThat(it.immutable).isNotSameAs(immutable);
|
||||
assertThat(it).isNotSameAs(outer);
|
||||
});
|
||||
}
|
||||
|
||||
@Value
|
||||
static class Order {
|
||||
Customer customer;
|
||||
@@ -100,4 +124,18 @@ public class PersistentPropertyAccessorUnitTests {
|
||||
static class Customer {
|
||||
String firstname;
|
||||
}
|
||||
|
||||
// DATACMNS-1322
|
||||
|
||||
@Value
|
||||
@Wither(AccessLevel.PACKAGE)
|
||||
static class NestedImmutable {
|
||||
String value;
|
||||
}
|
||||
|
||||
@Value
|
||||
@Wither(AccessLevel.PACKAGE)
|
||||
static class Outer {
|
||||
NestedImmutable immutable;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user