From 6326fe1ac7ae3838dd6efca47d5cc7898f4087b3 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Thu, 16 Nov 2023 15:01:03 +0100 Subject: [PATCH] Properly merge non-entity arrays. Fixes #2325. --- .../rest/webmvc/json/DomainObjectReader.java | 3 +- .../json/DomainObjectReaderUnitTests.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) 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 f85b96b4f..4d609a8bd 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 @@ -365,7 +365,8 @@ public class DomainObjectReader { if (array.isEmpty() || collection.isEmpty() || ClassUtils.isPrimitiveOrWrapper(componentType.getType()) - || componentType.getType().isEnum()) { + || componentType.getType().isEnum() + || !entities.getPersistentEntity(componentType.getType()).isPresent()) { return false; } 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 520b20f9b..2474e5e51 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 @@ -115,6 +115,7 @@ class DomainObjectReaderUnitTests { mappingContext.getPersistentEntity(Pear.class); mappingContext.getPersistentEntity(WithCustomMappedPrimitiveCollection.class); mappingContext.getPersistentEntity(BugModel.class); + mappingContext.getPersistentEntity(ArrayListHolder.class); mappingContext.afterPropertiesSet(); this.entities = new PersistentEntities(Collections.singleton(mappingContext)); @@ -704,6 +705,42 @@ class DomainObjectReaderUnitTests { .containsExactly("Foo", "Bar"); } + @Test // #2325 + void arraysCanMutateAndAppendDuringMerge() throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + ArrayHolder target = new ArrayHolder(new String[] { "ancient", "old", "older" }); + JsonNode node = mapper.readTree("{ \"array\" : [ \"new\", \"old\", \"newer\", \"bleeding edge\" ] }"); + + ArrayHolder updated = reader.doMerge((ObjectNode) node, target, mapper); + + assertThat(updated.array).containsExactly("new", "old", "newer", "bleeding edge"); + } + + @Test // #2325 + void arraysCanAppendMoreThanOneElementDuringMerge() throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + ArrayListHolder target = new ArrayListHolder("ancient", "old", "older"); + JsonNode node = mapper.readTree("{ \"values\" : [ \"ancient\", \"old\", \"older\", \"new\", \"newer\" ] }"); + + ArrayListHolder updated = reader.doMerge((ObjectNode) node, target, mapper); + + assertThat(updated.values).containsExactly("ancient", "old", "older", "new", "newer"); + } + + @Test // #2325 + void arraysCanRemoveElementsDuringMerge() throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + ArrayHolder target = new ArrayHolder(new String[] { "ancient", "old", "older" }); + JsonNode node = mapper.readTree("{ \"array\" : [ \"ancient\" ] }"); + + ArrayHolder updated = reader.doMerge((ObjectNode) node, target, mapper); + + assertThat(updated.array).containsExactly("ancient"); + } + @SuppressWarnings("unchecked") private static T as(Object source, Class type) { @@ -1000,4 +1037,16 @@ class DomainObjectReaderUnitTests { public String value; } } + + static class ArrayListHolder { + Collection values; + + ArrayListHolder(String... values) { + this.values = new ArrayList<>(Arrays.asList(values)); + } + + public void setValues(Collection values) { + this.values = values; + } + } }