diff --git a/pom.xml b/pom.xml
index 63af8ca470..3e4fd1df9a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.4.0-SNAPSHOT
+ 3.4.0-GH-3921-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index e2704a6753..38d850ec60 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
- 3.4.0-SNAPSHOT
+ 3.4.0-GH-3921-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index b75f8bf624..6766c0bec9 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -14,7 +14,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.4.0-SNAPSHOT
+ 3.4.0-GH-3921-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index ca96626cc9..b3165972f2 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -11,7 +11,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.4.0-SNAPSHOT
+ 3.4.0-GH-3921-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
index a360b8be91..1013628de8 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
@@ -1411,6 +1411,14 @@ public KeyMapper(String key,
this.currentIndex = 0;
}
+ String nextToken() {
+ return pathParts.get(currentIndex+1);
+ }
+
+ boolean hasNexToken() {
+ return pathParts.size() > currentIndex+1;
+ }
+
/**
* Maps the property name while retaining potential positional operator {@literal $}.
*
@@ -1420,31 +1428,25 @@ public KeyMapper(String key,
protected String mapPropertyName(MongoPersistentProperty property) {
StringBuilder mappedName = new StringBuilder(PropertyToFieldNameConverter.INSTANCE.convert(property));
+ if(!hasNexToken()) {
+ return mappedName.toString();
+ }
- boolean inspect = iterator.hasNext();
-
- while (inspect) {
-
- String partial = iterator.next();
- currentIndex++;
-
- boolean isPositional = isPositionalParameter(partial) && property.isCollectionLike();
- if (property.isMap() && currentPropertyRoot.equals(partial) && iterator.hasNext()) {
- partial = iterator.next();
- currentIndex++;
- }
-
- if (isPositional || property.isMap() && !currentPropertyRoot.equals(partial)) {
- mappedName.append(".").append(partial);
- }
+ String nextToken = nextToken();
+ if(isPositionalParameter(nextToken)) {
- inspect = isPositional && iterator.hasNext();
+ mappedName.append(".").append(nextToken);
+ currentIndex+=2;
+ return mappedName.toString();
}
- if (currentIndex + 1 < pathParts.size()) {
- currentIndex++;
- currentPropertyRoot = pathParts.get(currentIndex);
+ if(property.isMap()) {
+
+ mappedName.append(".").append(nextToken);
+ currentIndex+=2;
+ return mappedName.toString();
}
+ currentIndex++;
return mappedName.toString();
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java
index 15704af030..28d522fba9 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java
@@ -1309,6 +1309,36 @@ void updateListWithDocuRefOnProperty() {
assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("customers", Arrays.asList("c-name"))));
}
+ @Test // GH-3921
+ void mapNumericKeyInPathHavingComplexMapValyeTypes() {
+
+ Update update = new Update().set("testInnerData.testMap.1.intValue", "4");
+ Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
+ context.getPersistentEntity(TestData.class));
+
+ assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("testInnerData.testMap.1.intValue","4")));
+ }
+
+ @Test // GH-3921
+ void mapNumericKeyInPathNotMatchingExistingProperties() {
+
+ Update update = new Update().set("testInnerData.imaginaryMap.1.nonExistingProperty", "4");
+ Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
+ context.getPersistentEntity(TestData.class));
+
+ assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("testInnerData.imaginaryMap.1.noExistingProperty","4")));
+ }
+
+ @Test // GH-3921
+ void mapNumericKeyInPathPartiallyMatchingExistingProperties() {
+
+ Update update = new Update().set("testInnerData.testMap.1.nonExistingProperty.2.someValue", "4");
+ Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
+ context.getPersistentEntity(TestData.class));
+
+ assertThat(mappedUpdate).isEqualTo(new org.bson.Document("$set",new org.bson.Document("testInnerData.testMap.1.nonExistingProperty.2.someValue","4")));
+ }
+
static class DomainTypeWrappingConcreteyTypeHavingListOfInterfaceTypeAttributes {
ListModelWrapper concreteTypeWithListAttributeOfInterfaceType;
}
@@ -1710,4 +1740,20 @@ static class WithDocumentReference {
private List samples;
}
+ @Data
+ private static class TestData {
+ @Id
+ private String id;
+ private TestInnerData testInnerData;
+ }
+
+ @Data
+ private static class TestInnerData {
+ private Map testMap;
+ }
+
+ @Data
+ private static class TestValue {
+ private int intValue;
+ }
}