From d6d8c50592a85dabd36c84b2fffcbbd1d35f1e56 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Tue, 23 May 2023 15:51:53 +0200 Subject: [PATCH] Avoid manually handling additional primitive elements in collection merging for PATCHes. Fixes #2261. --- .../rest/webmvc/json/DomainObjectReader.java | 5 +- .../json/DomainObjectReaderUnitTests.java | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) 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 a909617ad..901f9ce55 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 @@ -352,10 +352,7 @@ private boolean handleArrayNode(ArrayNode array, Collection collection, for (JsonNode jsonNode : array) { if (!value.hasNext()) { - - collection.add(mapper.treeToValue(jsonNode, getTypeToMap(null, componentType).getType())); - - continue; + break; } Object next = value.next(); 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 9eb0711cd..25c94f5d1 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 @@ -58,6 +58,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; @@ -66,6 +67,8 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -109,6 +112,7 @@ void setUp() { mappingContext.getPersistentEntity(ArrayHolder.class); mappingContext.getPersistentEntity(Apple.class); mappingContext.getPersistentEntity(Pear.class); + mappingContext.getPersistentEntity(WithCustomMappedPrimitiveCollection.class); mappingContext.afterPropertiesSet(); this.entities = new PersistentEntities(Collections.singleton(mappingContext)); @@ -645,6 +649,21 @@ void nestedEntitiesWithReadonlyFieldAreKeptForPut() throws Exception { assertThat(result.inner).isSameAs(inner); } + @Test // GH-2261 + void deserializesCustomCollectionOfPrimitives() throws Exception { + + var node = new ObjectMapper().readTree(""" + { "longs" : [ "foo:1", "bar:2" ] } + """); + + var collection = new WithCustomMappedPrimitiveCollection(); + collection.longs = List.of(3L); + + var result = reader.doMerge((ObjectNode) node, collection, new ObjectMapper()); + + assertThat(result.longs).isEqualTo(List.of(1L, 2L)); + } + @SuppressWarnings("unchecked") private static T as(Object source, Class type) { @@ -900,4 +919,31 @@ static class Apple extends Fruit { static class Pear extends Fruit { String pear; } + + // GH-2261 + static class WithCustomMappedPrimitiveCollection { + + @JsonDeserialize(contentUsing = CustomDeserializer.class) // + List longs; + + @SuppressWarnings("serial") + static class CustomDeserializer extends StdDeserializer { + + protected CustomDeserializer() { + super(Long.class); + } + + /* + * (non-Javadoc) + * @see com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext) + */ + @Override + public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException { + + var elements = p.getText().split(":"); + + return Long.valueOf(elements[elements.length - 1]); + } + } + } }