DATAMONGO-1988 - Fix query creation for id property references using ObjectId hex String representation.

We now follow the conversion rules for id properties with a valid ObjectId representation when creating queries. Prior to this change e.g. String values would have been turned into ObejctIds when saving a document, but not when querying the latter.

Original pull request: #565.
This commit is contained in:
Christoph Strobl
2018-05-30 15:10:49 +02:00
committed by Mark Paluch
parent 2d9232ca04
commit 9f77aba8bb
3 changed files with 49 additions and 5 deletions

View File

@@ -312,7 +312,7 @@ public class QueryMapper {
@SuppressWarnings("unchecked")
protected Object getMappedValue(Field documentField, Object value) {
if (documentField.isIdField()) {
if (documentField.isIdField() && !documentField.isAssociation()) {
if (isDBObject(value)) {
DBObject valueDbo = (DBObject) value;
@@ -855,10 +855,11 @@ public class QueryMapper {
@Override
public boolean isIdField() {
MongoPersistentProperty idProperty = entity.getIdProperty();
MongoPersistentProperty idProperty = (property != null && property.isIdProperty()) ? property
: entity.getIdProperty();
if (idProperty != null) {
return idProperty.getName().equals(name) || idProperty.getFieldName().equals(name);
return name.endsWith(idProperty.getName()) || name.endsWith(idProperty.getFieldName());
}
return DEFAULT_ID_NAMES.contains(name);

View File

@@ -214,6 +214,7 @@ public class MongoTemplateTests {
template.dropCollection(Address.class);
template.dropCollection(DocumentWithCollectionOfSamples.class);
template.dropCollection(WithGeoJson.class);
template.dropCollection(DocumentWithNestedTypeHavingStringIdProperty.class);
}
@Test
@@ -3361,6 +3362,22 @@ public class MongoTemplateTests {
assertThat(template.count(query(where("field").is("stark")), Sample.class)).isEqualTo(0L);
}
@Test // DATAMONGO-1988
public void findByNestedDocumentWithStringIdMappingToObjectIdMatchesDocumentsCorrectly() {
DocumentWithNestedTypeHavingStringIdProperty source = new DocumentWithNestedTypeHavingStringIdProperty();
source.id = "id-1";
source.sample = new Sample();
source.sample.id = new ObjectId().toHexString();
template.save(source);
DocumentWithNestedTypeHavingStringIdProperty target = template.query(DocumentWithNestedTypeHavingStringIdProperty.class)
.matching(query(where("sample.id").is(source.sample.id))).firstValue();
assertThat(target).isEqualTo(source);
}
static class TypeWithNumbers {
@Id String id;
@@ -3462,6 +3479,13 @@ public class MongoTemplateTests {
List<Sample> samples;
}
@EqualsAndHashCode
static class DocumentWithNestedTypeHavingStringIdProperty {
@Id String id;
Sample sample;
}
static class DocumentWithMultipleCollections {
@Id String id;
List<String> string1;

View File

@@ -773,13 +773,32 @@ public class QueryMapperUnitTests {
assertThat(document.get("legacyPoint.y"), Is.<Object> is(20D));
}
@Test // DATAMONGO-1988
public void mapsStringObjectIdRepresentationToObjectIdWhenReferencingIdProperty() {
Query query = query(where("sample.foo").is(new ObjectId().toHexString()));
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(ClassWithEmbedded.class));
assertThat(document.get("sample._id"), instanceOf(ObjectId.class));
}
@Test // DATAMONGO-1988
public void leavesNonObjectIdStringIdRepresentationUntouchedWhenReferencingIdProperty() {
Query query = query(where("sample.foo").is("id-1"));
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(ClassWithEmbedded.class));
assertThat(document.get("sample._id"), instanceOf(String.class));
}
@Document
public class Foo {
@Id private ObjectId id;
EmbeddedClass embedded;
@Field("my_items")
List<EmbeddedClass> listOfItems;
@Field("my_items") List<EmbeddedClass> listOfItems;
}
public class EmbeddedClass {