DATAMONGO-2488 - Fix nested array path field name mapping.
Original pull request: #841.
This commit is contained in:
committed by
Mark Paluch
parent
5a49aa6519
commit
7f7be5e47d
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user