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 7a14f07c4c..fbc7769ffc 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 @@ -1020,8 +1020,8 @@ public TypeInformation getTypeHint() { */ protected static class MetadataBackedField extends Field { - private static final Pattern POSITIONAL_PARAMETER_PATTERN = Pattern.compile("\\.\\$(\\[.*?\\])?|\\.\\d+"); - private static final Pattern DOT_POSITIONAL_PATTERN = Pattern.compile("\\.\\d+"); + private static final Pattern POSITIONAL_PARAMETER_PATTERN = Pattern.compile("\\.\\$(\\[.*?\\])?"); + private static final Pattern DOT_POSITIONAL_PATTERN = Pattern.compile("\\.\\d+(?!$)"); private static final String INVALID_ASSOCIATION_REFERENCE = "Invalid path reference %s! Associations can only be pointed to directly or via their id property!"; private final MongoPersistentEntity entity; diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index efd354b866..486fb9c37f 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -59,6 +59,7 @@ import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.TextQuery; +import org.springframework.data.mongodb.core.query.Update; import com.mongodb.BasicDBObject; import com.mongodb.MongoClientSettings; @@ -1334,6 +1335,25 @@ void mapStringIdFieldProjection() { org.bson.Document mappedFields = mapper.getMappedFields(new org.bson.Document("id", 1), context.getPersistentEntity(WithStringId.class)); assertThat(mappedFields).containsEntry("_id", 1); } + + @Test + void mapNestedStringFieldCorrectly() { + Update update = new Update(); + update.set("levelOne.a.b.d", "e"); + org.bson.Document document = mapper.getMappedObject(update.getUpdateObject(), + context.getPersistentEntity(EntityWithNestedMap.class)); + assertThat(document).isEqualTo(new org.bson.Document("$set",new org.bson.Document("levelOne.a.b.d","e"))); + } + + @Test + void mapNestedIntegerFieldCorrectly() { + Update update = new Update(); + update.set("levelOne.0.1.3", "4"); + org.bson.Document document = mapper.getMappedObject(update.getUpdateObject(), + context.getPersistentEntity(EntityWithNestedMap.class)); + assertThat(document).isEqualTo(new org.bson.Document("$set",new org.bson.Document("levelOne.0.1.3","4"))); + } + class WithDeepArrayNesting { @@ -1497,6 +1517,11 @@ static class EntityWithIntKeyedMapOfMap{ static class EntityWithComplexValueTypeList { List list; } + + static class EntityWithNestedMap { + Map>> levelOne; + } + static class WithExplicitTargetTypes {