diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java index 901f9ce55..593e1a50c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/DomainObjectReader.java @@ -40,7 +40,6 @@ import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.rest.webmvc.mapping.Associations; import org.springframework.data.rest.webmvc.util.InputStreamHttpInputMessage; import org.springframework.data.util.ClassTypeInformation; -import org.springframework.data.util.Optionals; import org.springframework.data.util.TypeInformation; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.lang.Nullable; @@ -677,7 +676,10 @@ public class DomainObjectReader { } else if (property.isCollectionLike()) { result = mergeCollections(property, sourceValue, targetValue, mapper); } else if (property.isEntity()) { - result = Optionals.mapIfAllPresent(sourceValue, targetValue, (l, r) -> mergeForPut(l, r, mapper)); + + result = targetValue.isEmpty() + ? sourceValue + : targetValue.flatMap(t -> sourceValue.map(s -> mergeForPut(s, t, mapper))); } else { result = sourceValue; } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java index 25c94f5d1..92ecc2bba 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/DomainObjectReaderUnitTests.java @@ -664,6 +664,26 @@ class DomainObjectReaderUnitTests { assertThat(result.longs).isEqualTo(List.of(1L, 2L)); } + @Test // GH-2264 + void nestedEntitiesAreCreatedWhenMissingForPut() throws Exception { + + var outer = new Outer(); + outer.name = "outer name"; + outer.prop = "something"; + + var node = new ObjectMapper().readTree( + "{ \"inner\" : { \"name\" : \"new inner name\", \"readOnly\" : \"readonly value\", \"hidden\" : \"hidden value\" } }"); + + var result = reader.readPut((ObjectNode) node, outer, new ObjectMapper()); + + assertThat(result).isSameAs(outer); + assertThat(result.inner).isNotNull(); + assertThat(result.inner.prop).isNull(); + assertThat(result.inner.name).isEqualTo("new inner name"); + assertThat(result.inner.readOnly).isNull(); + assertThat(result.inner.hidden).isNull(); + } + @SuppressWarnings("unchecked") private static T as(Object source, Class type) {