Skip to content

Commit 129ea2a

Browse files
committed
DATAREST-837 - DomainObjectMerger doesn't nullify read-only properties on PUT.
PUT requests are supposed to replace the state of the resource with the request payload. However, Spring Data REST already handles a couple of domain object propoerties in a special way as theri values map to dedicated HTTP features: identifiers (URIs), last-modified dates (header) etc. For users, it might be worthwhile to exclude other properties from being set by applying the payload, like properties that are completely under the control of the server, e.g. creation user and date, last modifying user etc. So far, users didn't have any means to exclude those properties as the handling of PUT requests treated every missing property of the payload as null value. DomainObjectMerger now checks whether a property is actually writable before applying the implicit null value. The application can be disabled by annotation a property with @ReadOnlyProperty.
1 parent 0cae0e5 commit 129ea2a

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public <T> T readPut(final ObjectNode source, T target, final ObjectMapper mappe
121121
@Override
122122
public void doWithPersistentProperty(PersistentProperty<?> property) {
123123

124-
if (property.isIdProperty() || property.isVersionProperty()) {
124+
if (property.isIdProperty() || property.isVersionProperty() || !property.isWritable()) {
125125
return;
126126
}
127127

spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.junit.Assert.*;
2020

2121
import java.util.Collections;
22+
import java.util.Date;
2223
import java.util.HashMap;
2324
import java.util.Map;
2425

@@ -27,7 +28,9 @@
2728
import org.junit.runner.RunWith;
2829
import org.mockito.Mock;
2930
import org.mockito.runners.MockitoJUnitRunner;
31+
import org.springframework.data.annotation.CreatedDate;
3032
import org.springframework.data.annotation.Id;
33+
import org.springframework.data.annotation.ReadOnlyProperty;
3134
import org.springframework.data.annotation.Version;
3235
import org.springframework.data.mapping.context.PersistentEntities;
3336
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
@@ -61,6 +64,7 @@ public void setUp() {
6164
mappingContext.getPersistentEntity(Person.class);
6265
mappingContext.getPersistentEntity(TypeWithGenericMap.class);
6366
mappingContext.getPersistentEntity(VersionedType.class);
67+
mappingContext.getPersistentEntity(SampleWithCreatedDate.class);
6468
mappingContext.afterPropertiesSet();
6569

6670
PersistentEntities entities = new PersistentEntities(Collections.singleton(mappingContext));
@@ -169,6 +173,23 @@ public void doesNotWipeIdAndVersionPropertyForPut() throws Exception {
169173
assertThat(result.version, is(1L));
170174
}
171175

176+
/**
177+
* @see DATAREST-873
178+
*/
179+
@Test
180+
public void doesNotApplyInputToReadOnlyFields() throws Exception {
181+
182+
ObjectMapper mapper = new ObjectMapper();
183+
ObjectNode node = (ObjectNode) mapper.readTree("{}");
184+
185+
Date reference = new Date();
186+
187+
SampleWithCreatedDate sample = new SampleWithCreatedDate();
188+
sample.createdDate = reference;
189+
190+
assertThat(reader.readPut(node, sample, mapper).createdDate, is(reference));
191+
}
192+
172193
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
173194
static class SampleUser {
174195

@@ -210,4 +231,12 @@ static class VersionedType {
210231

211232
String firstname, lastname;
212233
}
234+
235+
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
236+
static class SampleWithCreatedDate {
237+
238+
@CreatedDate //
239+
@ReadOnlyProperty //
240+
Date createdDate;
241+
}
213242
}

0 commit comments

Comments
 (0)