DATAMONGO-2488 - Fix nested array path field name mapping.

Original pull request: #841.
This commit is contained in:
Christoph Strobl
2020-03-11 10:30:28 +01:00
committed by Mark Paluch
parent 5a49aa6519
commit 7f7be5e47d
3 changed files with 97 additions and 11 deletions

View File

@@ -24,7 +24,6 @@ import org.bson.BsonValue;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Example;
@@ -175,7 +174,7 @@ public class QueryMapper {
}
Document mappedSort = new Document();
for(Map.Entry<String,Object> entry : BsonUtils.asMap(sortObject).entrySet()) {
for (Map.Entry<String, Object> entry : BsonUtils.asMap(sortObject).entrySet()) {
Field field = createPropertyField(entity, entry.getKey(), mappingContext);
mappedSort.put(field.getMappedKey(), entry.getValue());
@@ -1158,7 +1157,7 @@ public class QueryMapper {
* @return
*/
protected Converter<MongoPersistentProperty, String> getPropertyConverter() {
return new PositionParameterRetainingPropertyKeyConverter(name);
return new PositionParameterRetainingPropertyKeyConverter(name, mappingContext);
}
/**
@@ -1172,6 +1171,10 @@ public class QueryMapper {
return new AssociationConverter(getAssociation());
}
protected MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getMappingContext() {
return mappingContext;
}
/**
* @author Christoph Strobl
* @since 1.8
@@ -1180,8 +1183,9 @@ public class QueryMapper {
private final KeyMapper keyMapper;
public PositionParameterRetainingPropertyKeyConverter(String rawKey) {
this.keyMapper = new KeyMapper(rawKey);
public PositionParameterRetainingPropertyKeyConverter(String rawKey,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> ctx) {
this.keyMapper = new KeyMapper(rawKey, ctx);
}
/*
@@ -1222,11 +1226,14 @@ public class QueryMapper {
static class KeyMapper {
private final Iterator<String> iterator;
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
public KeyMapper(String key) {
public KeyMapper(String key,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
this.iterator = Arrays.asList(key.split("\\.")).iterator();
this.iterator.next();
this.mappingContext = mappingContext;
}
/**
@@ -1240,9 +1247,22 @@ public class QueryMapper {
StringBuilder mappedName = new StringBuilder(PropertyToFieldNameConverter.INSTANCE.convert(property));
boolean inspect = iterator.hasNext();
int depth = 0;
while (inspect) {
String partial = iterator.next();
if (depth > 0 && property.isCollectionLike()) {
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(property.getComponentType());
if (persistentEntity != null) {
MongoPersistentProperty persistentProperty = persistentEntity.getPersistentProperty(partial);
if(persistentProperty != null) {
partial = mapPropertyName(persistentProperty);
}
}
}
boolean isPositional = (isPositionalParameter(partial) && (property.isMap() || property.isCollectionLike()));
if (isPositional) {
@@ -1250,6 +1270,7 @@ public class QueryMapper {
}
inspect = isPositional && iterator.hasNext();
depth++;
}
return mappedName.toString();

View File

@@ -308,7 +308,7 @@ public class UpdateMapper extends QueryMapper {
*/
@Override
protected Converter<MongoPersistentProperty, String> getPropertyConverter() {
return new PositionParameterRetainingPropertyKeyConverter(key);
return new PositionParameterRetainingPropertyKeyConverter(key, getMappingContext());
}
/*
@@ -317,7 +317,7 @@ public class UpdateMapper extends QueryMapper {
*/
@Override
protected Converter<MongoPersistentProperty, String> getAssociationConverter() {
return new UpdateAssociationConverter(getAssociation(), key);
return new UpdateAssociationConverter(getMappingContext(), getAssociation(), key);
}
/**
@@ -334,10 +334,12 @@ public class UpdateMapper extends QueryMapper {
*
* @param association must not be {@literal null}.
*/
public UpdateAssociationConverter(Association<MongoPersistentProperty> association, String key) {
public UpdateAssociationConverter(
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext,
Association<MongoPersistentProperty> association, String key) {
super(association);
this.mapper = new KeyMapper(key);
this.mapper = new KeyMapper(key, mappingContext);
}
/*

View File

@@ -36,7 +36,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
@@ -927,6 +926,70 @@ public class QueryMapperUnitTests {
assertThat(target).isEqualTo(org.bson.Document.parse("{\"_id\": {\"$in\": [{\"$oid\": \"" + id + "\"}]}}"));
}
@Test // DATAMONGO-2488
public void mapsNestedArrayPathCorrectlyForNonMatchingPath() {
org.bson.Document target = mapper.getMappedObject(
query(where("array.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(Foo.class));
assertThat(target).isEqualTo(new org.bson.Document("array.$[some_item].nested.$[other_item]", "value"));
}
@Test // DATAMONGO-2488
public void mapsNestedArrayPathCorrectlyForObjectTargetArray() {
org.bson.Document target = mapper.getMappedObject(
query(where("arrayObj.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(WithNestedArray.class));
assertThat(target).isEqualTo(new org.bson.Document("arrayObj.$[some_item].nested.$[other_item]", "value"));
}
@Test // DATAMONGO-2488
public void mapsNestedArrayPathCorrectlyForStringTargetArray() {
org.bson.Document target = mapper.getMappedObject(
query(where("arrayString.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(WithNestedArray.class));
assertThat(target).isEqualTo(new org.bson.Document("arrayString.$[some_item].nested.$[other_item]", "value"));
}
@Test // DATAMONGO-2488
public void mapsCustomFieldNamesForNestedArrayPathCorrectly() {
org.bson.Document target = mapper.getMappedObject(
query(where("arrayCustomName.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(WithNestedArray.class));
assertThat(target).isEqualTo(new org.bson.Document("arrayCustomName.$[some_item].nes-ted.$[other_item]", "value"));
}
class WithNestedArray {
List<NestedArrayOfObj> arrayObj;
List<NestedArrayOfString> arrayString;
List<NestedArrayOfObjCustomFieldName> arrayCustomName;
}
class NestedArrayOfObj {
List<ArrayObj> nested;
}
class NestedArrayOfObjCustomFieldName {
@Field("nes-ted") List<ArrayObj> nested;
}
class NestedArrayOfString {
List<String> nested;
}
class ArrayObj {
String foo;
}
@Document
class Foo {
@Id private ObjectId id;