Skip to content

Fix query mapping resolution of properties using underscore within field name. #3607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3601-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data MongoDB</name>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3601-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3601-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.2.0-SNAPSHOT</version>
<version>3.2.0-GH-3601-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ private PersistentPropertyPath<MongoPersistentProperty> getPath(String pathExpre

if (sourceProperty != null && sourceProperty.getOwner().equals(entity)) {
return mappingContext
.getPersistentPropertyPath(PropertyPath.from(sourceProperty.getName(), entity.getTypeInformation()));
.getPersistentPropertyPath(PropertyPath.from(Pattern.quote(sourceProperty.getName()), entity.getTypeInformation()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it rather make sense to fix that issue in Commons? Property path creation does all sorts of string transformations and lookups (Decapitalize, owningType.getProperty(propertyName)) while regex matching is a small part of the entire process.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is yes - for the upcoming service release I'd tough rather have the regression fixed in this project and investigate a fix for commons in the upcoming release cycle as it may lead to unintentional behaviour in other modules.

}

PropertyPath path = forName(rawPath);
Expand Down Expand Up @@ -1229,6 +1229,13 @@ private PropertyPath forName(String path) {
return forName(path.substring(0, path.length() - 3) + "id");
}

// Ok give it another try quoting
try {
return PropertyPath.from(Pattern.quote(path), entity.getTypeInformation());
} catch (PropertyReferenceException | InvalidPersistentPropertyPath ex) {

}

return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,72 @@ void projectOnEmbeddableValue() {
assertThat(document).isEqualTo(new org.bson.Document("stringValue", 1));
}

@Test // GH-3601
void resolvesFieldnameWithUnderscoresCorrectly() {

Query query = query(where("fieldname_with_underscores").exists(true));

org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(WithPropertyUsingUnderscoreInName.class));

assertThat(document).isEqualTo(new org.bson.Document("fieldname_with_underscores", new org.bson.Document("$exists", true)));
}

@Test // GH-3601
void resolvesMappedFieldnameWithUnderscoresCorrectly() {

Query query = query(where("renamed_fieldname_with_underscores").exists(true));

org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(WithPropertyUsingUnderscoreInName.class));

assertThat(document).isEqualTo(new org.bson.Document("renamed", new org.bson.Document("$exists", true)));
}

@Test // GH-3601
void resolvesSimpleNestedFieldnameWithUnderscoresCorrectly() {

Query query = query(where("simple.fieldname_with_underscores").exists(true));

org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));

assertThat(document).isEqualTo(new org.bson.Document("simple.fieldname_with_underscores", new org.bson.Document("$exists", true)));
}

@Test // GH-3601
void resolvesSimpleNestedMappedFieldnameWithUnderscoresCorrectly() {

Query query = query(where("simple.renamed_fieldname_with_underscores").exists(true));

org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));

assertThat(document).isEqualTo(new org.bson.Document("simple.renamed", new org.bson.Document("$exists", true)));
}

@Test // GH-3601
void resolvesFieldNameWithUnderscoreOnNestedFieldnameWithUnderscoresCorrectly() {

Query query = query(where("double_underscore.fieldname_with_underscores").exists(true));

org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));

assertThat(document).isEqualTo(new org.bson.Document("double_underscore.fieldname_with_underscores", new org.bson.Document("$exists", true)));
}

@Test // GH-3601
void resolvesFieldNameWithUnderscoreOnNestedMappedFieldnameWithUnderscoresCorrectly() {

Query query = query(where("double_underscore.renamed_fieldname_with_underscores").exists(true));

org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));

assertThat(document).isEqualTo(new org.bson.Document("double_underscore.renamed", new org.bson.Document("$exists", true)));
}

class WithDeepArrayNesting {

List<WithNestedArray> level0;
Expand Down Expand Up @@ -1408,4 +1474,17 @@ static class EmbeddableType {
String transientValue;
}

static class WrapperAroundWithPropertyUsingUnderscoreInName {

WithPropertyUsingUnderscoreInName simple;
WithPropertyUsingUnderscoreInName double_underscore;
}

static class WithPropertyUsingUnderscoreInName {

String fieldname_with_underscores;

@Field("renamed")
String renamed_fieldname_with_underscores;
}
}