diff --git a/pom.xml b/pom.xml
index aff1afc489..ec0d667da1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.3.0-SNAPSHOT
+ 4.3.x-4571-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index 34d95eb205..76732159c0 100644
--- a/spring-data-mongodb-benchmarks/pom.xml
+++ b/spring-data-mongodb-benchmarks/pom.xml
@@ -7,7 +7,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.3.0-SNAPSHOT
+ 4.3.x-4571-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 124a6bf5ad..5c21192bcd 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -15,7 +15,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.3.0-SNAPSHOT
+ 4.3.x-4571-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index 39fc1a1de9..651bf35a1c 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.3.0-SNAPSHOT
+ 4.3.x-4571-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java
index eebd948a14..331cbb2e86 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java
@@ -593,7 +593,7 @@ public static boolean hasValue(Bson bson, FieldName fieldName) {
Map source = asMap(bson);
if (fieldName.isKey()) {
- return source.get(fieldName.name()) != null;
+ return source.containsKey(fieldName.name());
}
String[] parts = fieldName.parts();
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 47c7a0027b..9815ce23b9 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
@@ -27,6 +27,8 @@
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Stream;
import org.bson.BsonUndefined;
import org.bson.types.Binary;
@@ -38,6 +40,8 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.mockito.Mockito;
@@ -673,6 +677,15 @@ void readsListOfMapsCorrectly() {
assertThat(wrapper.listOfMaps.get(0).get("Foo")).isEqualTo(Locale.ENGLISH);
}
+ @ParameterizedTest // GH-4571
+ @MethodSource("listMapSetReadingSource")
+ void initializesListMapSetPropertiesIfRequiredOnRead(org.bson.Document source, Class type,
+ Function valueFunction, Object expectedValue) {
+
+ T target = converter.read(type, source);
+ assertThat(target).extracting(valueFunction).isEqualTo(expectedValue);
+ }
+
@Test // DATAMONGO-259
void writesPlainMapOfCollectionsCorrectly() {
@@ -2986,6 +2999,49 @@ org.bson.Document write(Object source) {
return target;
}
+ private static Stream listMapSetReadingSource() {
+
+ Function contacts = CollectionWrapper::getContacts;
+ Function contactsSet = CollectionWrapper::getContactsSet;
+ Function autoInitList = CollectionWrapper::getAutoInitList;
+ Function map = ClassWithMapProperty::getMap;
+ Function autoInitMap = ClassWithMapProperty::getAutoInitMap;
+
+ return Stream.of( //
+
+ // List
+ Arguments.of(new org.bson.Document("contacts", Collections.emptyList()), CollectionWrapper.class, contacts,
+ Collections.emptyList()),
+ Arguments.of(new org.bson.Document("contacts", null), CollectionWrapper.class, contacts, null),
+ Arguments.of(new org.bson.Document(), CollectionWrapper.class, contacts, null),
+
+ // ctor initialized List
+ Arguments.of(new org.bson.Document("autoInitList", Collections.emptyList()), CollectionWrapper.class,
+ autoInitList, Collections.emptyList()),
+ Arguments.of(new org.bson.Document("autoInitList", null), CollectionWrapper.class, autoInitList, null),
+ Arguments.of(new org.bson.Document(), CollectionWrapper.class, autoInitList,
+ Collections.singletonList("spring")),
+
+ // Set
+ Arguments.of(new org.bson.Document("contactsSet", Collections.emptyList()), CollectionWrapper.class,
+ contactsSet, Collections.emptySet()),
+ Arguments.of(new org.bson.Document("contactsSet", null), CollectionWrapper.class, contactsSet, null),
+ Arguments.of(new org.bson.Document(), CollectionWrapper.class, contactsSet, null),
+
+ // Map
+ Arguments.of(new org.bson.Document("map", new org.bson.Document()), ClassWithMapProperty.class, map,
+ Collections.emptyMap()),
+ Arguments.of(new org.bson.Document("map", null), ClassWithMapProperty.class, map, null),
+ Arguments.of(new org.bson.Document(), ClassWithMapProperty.class, map, null),
+
+ // ctor initialized Map
+ Arguments.of(new org.bson.Document("autoInitMap", new org.bson.Document()), ClassWithMapProperty.class,
+ autoInitMap, Collections.emptyMap()),
+ Arguments.of(new org.bson.Document("autoInitMap", null), ClassWithMapProperty.class, autoInitMap, null),
+ Arguments.of(new org.bson.Document(), ClassWithMapProperty.class, autoInitMap,
+ Collections.singletonMap("spring", "data")));
+ }
+
static class GenericType {
T content;
}
@@ -3142,11 +3198,20 @@ static class ClassWithSortedMap {
static class ClassWithMapProperty {
Map map;
+ Map autoInitMap = Collections.singletonMap("spring", "data");
Map> mapOfLists;
Map mapOfObjects;
Map mapOfStrings;
Map mapOfPersons;
TreeMap treeMapOfPersons;
+
+ public Map getMap() {
+ return map;
+ }
+
+ public Map getAutoInitMap() {
+ return this.autoInitMap;
+ }
}
static class ClassWithNestedMaps {
@@ -3168,6 +3233,19 @@ static class CollectionWrapper {
List> strings;
List