From bdc662ebe3614165b139c85fd0630828d787497f Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 6 May 2022 10:38:59 +0200 Subject: [PATCH] Apply conversion on document reference lookup using nested property. Closes #4033 Original pull request: #4044. --- .../mongodb/core/convert/QueryMapper.java | 28 +++++++++++++------ .../core/convert/QueryMapperUnitTests.java | 25 +++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java index 5afa39730..7b0ca6024 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java @@ -376,7 +376,9 @@ public class QueryMapper { if (keyword.isOrOrNor() || (keyword.hasIterableValue() && !keyword.isGeometry())) { Iterable conditions = keyword.getValue(); - List newConditions = conditions instanceof Collection ? new ArrayList<>(((Collection) conditions).size()) : new ArrayList<>(); + List newConditions = conditions instanceof Collection + ? new ArrayList<>(((Collection) conditions).size()) + : new ArrayList<>(); for (Object condition : conditions) { newConditions.add(isDocument(condition) ? getMappedObject((Document) condition, entity) @@ -434,8 +436,10 @@ public class QueryMapper { Object value = applyFieldTargetTypeHintToValue(documentField, sourceValue); - if(documentField.getProperty() != null && converter.getCustomConversions().getPropertyValueConversions().hasValueConverter(documentField.getProperty())) { - return converter.getCustomConversions().getPropertyValueConversions().getValueConverter(documentField.getProperty()) + if (documentField.getProperty() != null + && converter.getCustomConversions().getPropertyValueConversions().hasValueConverter(documentField.getProperty())) { + return converter.getCustomConversions().getPropertyValueConversions() + .getValueConverter(documentField.getProperty()) .write(value, new MongoConversionContext(documentField.getProperty(), converter)); } @@ -619,7 +623,11 @@ public class QueryMapper { } protected Object convertAssociation(Object source, Field field) { - return convertAssociation(source, field.getProperty()); + Object value = convertAssociation(source, field.getProperty()); + if (value != null && field.isIdField() && field.getFieldType() != value.getClass()) { + return convertId(value, field.getFieldType()); + } + return value; } /** @@ -1045,6 +1053,9 @@ public class QueryMapper { return ClassTypeInformation.OBJECT; } + public Class getFieldType() { + return Object.class; + } } /** @@ -1197,10 +1208,11 @@ public class QueryMapper { return null; } - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.core.convert.QueryMapper.Field#getTargetKey() - */ + @Override + public Class getFieldType() { + return property.getFieldType(); + } + @Override public String getMappedKey() { return path == null ? name : path.toDotPath(isAssociation() ? getAssociationConverter() : getPropertyConverter()); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index d3b73379b..06f6aec93 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -437,6 +437,31 @@ public class QueryMapperUnitTests { assertThat(mappedQuery).containsEntry("sample", "s1"); } + @Test // GH-4033 + void convertsNestedPathToIdPropertyOfDocumentReferenceCorrectly() { + + Query query = query(where("sample.foo").is("s1")); + org.bson.Document mappedQuery = mapper.getMappedObject(query.getQueryObject(), + context.getPersistentEntity(WithDocumentReference.class)); + + assertThat(mappedQuery).containsEntry("sample", "s1"); + } + + @Test // GH-4033 + void convertsNestedPathToIdPropertyOfDocumentReferenceCorrectlyWhenItShouldBeConvertedToObjectId() { + + ObjectId id = new ObjectId(); + Query query = query(where("sample.foo").is(id.toHexString())); + org.bson.Document mappedQuery = mapper.getMappedObject(query.getQueryObject(), + context.getPersistentEntity(WithDocumentReference.class)); + + assertThat(mappedQuery.get("sample")).satisfies(it -> { + + assertThat(it).isInstanceOf(ObjectId.class); + assertThat(((ObjectId) it).toHexString()).isEqualTo(id.toHexString()); + }); + } + @Test // GH-3853 void convertsListDocumentReferenceOnIdPropertyCorrectly() {