Browse Source

DATAMONGO-2221 - Fix mapping of Strings matching a valid ObjectId for unresolvable paths.

We now make sure we to not convert Strings representing valid ObjectIds into the such for paths that cannot be resolved to a Property.

Original pull request: #732.
pull/792/head
Christoph Strobl 7 years ago committed by Mark Paluch
parent
commit
dc40c42815
  1. 36
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
  2. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java

36
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java

@ -914,9 +914,7 @@ public class QueryMapper { @@ -914,9 +914,7 @@ public class QueryMapper {
MongoPersistentProperty idProperty = entity.getIdProperty();
if (idProperty != null) {
return name.equals(idProperty.getName()) || name.equals(idProperty.getFieldName())
|| name.endsWith("." + idProperty.getName()) || name.endsWith("." + idProperty.getFieldName());
return name.equals(idProperty.getName()) || name.equals(idProperty.getFieldName());
}
return DEFAULT_ID_NAMES.contains(name);
@ -1004,14 +1002,15 @@ public class QueryMapper { @@ -1004,14 +1002,15 @@ public class QueryMapper {
@Nullable
private PersistentPropertyPath<MongoPersistentProperty> getPath(String pathExpression) {
try {
PropertyPath path = PropertyPath.from(pathExpression.replaceAll("\\.\\d+", ""), entity.getTypeInformation());
String rawPath = pathExpression.replaceAll("\\.\\d+", "");
if (isPathToJavaLangClassProperty(path)) {
PropertyPath path = forName(rawPath);
if (path == null || isPathToJavaLangClassProperty(path)) {
return null;
}
try {
PersistentPropertyPath<MongoPersistentProperty> propertyPath = mappingContext.getPersistentPropertyPath(path);
Iterator<MongoPersistentProperty> iterator = propertyPath.iterator();
@ -1032,7 +1031,30 @@ public class QueryMapper { @@ -1032,7 +1031,30 @@ public class QueryMapper {
}
return propertyPath;
} catch (InvalidPersistentPropertyPath e) {
return null;
}
}
/**
* Querydsl happens to map id fields directly to {@literal _id} which breaks {@link PropertyPath} resolution. So if
* the first attempt fails we try to replace {@literal _id} with just {@literal id} and see if we can resolve if
* then.
*
* @param path
* @return the path or {@literal null}
*/
@Nullable
private PropertyPath forName(String path) {
try {
return PropertyPath.from(path, entity.getTypeInformation());
} catch (PropertyReferenceException | InvalidPersistentPropertyPath e) {
if (path.endsWith("_id")) {
return forName(path.substring(0, path.length() - 3) + "id");
}
return null;
}
}

29
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java

@ -831,6 +831,30 @@ public class QueryMapperUnitTests { @@ -831,6 +831,30 @@ public class QueryMapperUnitTests {
assertThat(document).isEqualTo(new org.bson.Document("nested.id", idHex));
}
@Test // DATAMONGO-2221
public void shouldNotConvertHexStringToObjectIdForRenamedDeeplyNestedIdField() {
String idHex = new ObjectId().toHexString();
Query query = new Query(where("nested.deeplyNested.id").is(idHex));
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(RootForClassWithExplicitlyRenamedIdField.class));
assertThat(document).isEqualTo(new org.bson.Document("nested.deeplyNested.id", idHex));
}
@Test // DATAMONGO-2221
public void shouldNotConvertHexStringToObjectIdForUnresolvablePath() {
String idHex = new ObjectId().toHexString();
Query query = new Query(where("nested.unresolvablePath.id").is(idHex));
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(RootForClassWithExplicitlyRenamedIdField.class));
assertThat(document).isEqualTo(new org.bson.Document("nested.unresolvablePath.id", idHex));
}
@Document
public class Foo {
@Id private ObjectId id;
@ -926,6 +950,11 @@ public class QueryMapperUnitTests { @@ -926,6 +950,11 @@ public class QueryMapperUnitTests {
static class ClassWithExplicitlyRenamedField {
@Field("id") String id;
DeeplyNestedClassWithExplicitlyRenamedField deeplyNested;
}
static class DeeplyNestedClassWithExplicitlyRenamedField {
@Field("id") String id;
}
static class ClassWithGeoTypes {

Loading…
Cancel
Save