diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index eb71a2aab..88d3e72a1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -1136,7 +1136,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } for (Object element : source) { - items.add(context.convert(element, componentType)); + items.add(element != null ? context.convert(element, componentType) : element); } return getPotentiallyConvertedSimpleRead(items, targetType.getType()); @@ -1880,6 +1880,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @SuppressWarnings("unchecked") public S convert(Object source, TypeInformation typeHint) { + Assert.notNull(source, "Source must not be null"); Assert.notNull(typeHint, "TypeInformation must not be null"); if (conversions.hasCustomReadTarget(source.getClass(), typeHint.getType())) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index ba8fea622..494439594 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -2520,6 +2520,41 @@ class MappingMongoConverterUnitTests { assertThat(target.typeImplementingMap).isEqualTo(new TypeImplementingMap("one", 2)); } + @Test // GH-3686 + void readsCollectionContainingNullValue() { + + org.bson.Document source = new org.bson.Document("items", Arrays.asList(new org.bson.Document("itemKey", "i1"), null, new org.bson.Document("itemKey", "i3"))); + + Order target = converter.read(Order.class, source); + + assertThat(target.items) + .map(it -> it != null ? it.itemKey : null) + .containsExactly("i1", null, "i3"); + } + + @Test // GH-3686 + void readsArrayContainingNullValue() { + + org.bson.Document source = new org.bson.Document("arrayOfStrings", Arrays.asList("i1", null, "i3")); + + WithArrays target = converter.read(WithArrays.class, source); + + assertThat(target.arrayOfStrings).containsExactly("i1", null, "i3"); + } + + @Test // GH-3686 + void readsMapContainingNullValue() { + + org.bson.Document source = new org.bson.Document("mapOfObjects", new org.bson.Document("item1", "i1").append("item2", null).append("item3", "i3")); + + ClassWithMapProperty target = converter.read(ClassWithMapProperty.class, source); + + assertThat(target.mapOfObjects) + .containsEntry("item1", "i1") + .containsEntry("item2", null) + .containsEntry("item3", "i3"); + } + static class GenericType { T content; } @@ -2881,6 +2916,10 @@ class MappingMongoConverterUnitTests { } + static class WithArrays { + String[] arrayOfStrings; + } + // DATAMONGO-1898 // DATACMNS-1278