Skip to content

Commit

Permalink
Properly merge non-entity arrays.
Browse files Browse the repository at this point in the history
Fixes #2325.
  • Loading branch information
odrotbohm committed Nov 16, 2023
1 parent 50f2863 commit fc7452b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,8 @@ <T> T doMerge(ObjectNode root, T target, ObjectMapper mapper) throws Exception {

if (child.isArray()) {

IntFunction<Object> rawValues = index -> readRawCollectionElement(property.getComponentType(), fieldName, index,
root,
mapper);
IntFunction<Object> rawValues = index -> readRawCollectionElement(property.getComponentType(), fieldName,
index, root, mapper);

if (handleArray(child, it, mapper, property.getTypeInformation(), rawValues)) {
i.remove();
Expand Down Expand Up @@ -366,7 +365,8 @@ private boolean handleArrayNode(ArrayNode array, Collection<Object> collection,
if (array.isEmpty()
|| collection.isEmpty()
|| ClassUtils.isPrimitiveOrWrapper(componentType.getType())
|| componentType.getType().isEnum()) {
|| componentType.getType().isEnum()
|| entities.getPersistentEntity(componentType.getType()).isEmpty()) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ void setUp() {
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));
Expand Down Expand Up @@ -705,6 +706,42 @@ void deserializesNewNestedEntitiesCorrectly() throws Exception {
.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> T as(Object source, Class<T> type) {

Expand Down Expand Up @@ -997,4 +1034,16 @@ static class NestedModel {
public String value;
}
}

static class ArrayListHolder {
Collection<String> values;

ArrayListHolder(String... values) {
this.values = new ArrayList<>(Arrays.asList(values));
}

public void setValues(Collection<String> values) {
this.values = values;
}
}
}

0 comments on commit fc7452b

Please sign in to comment.