Fix field projection value conversion.

The field projection conversion should actually only map field names and avoid value conversion. In the MongoId case an inclusion parameter (1) was unintentionally converted into its String representation which causes trouble on Mongo 4.4 servers.

Fixes: #3668
Original pull request: #3678.
This commit is contained in:
Christoph Strobl
2021-06-21 12:24:02 +02:00
committed by Mark Paluch
parent 73a0f04933
commit 7dfe460433
2 changed files with 35 additions and 16 deletions

View File

@@ -195,19 +195,7 @@ public class QueryMapper {
return new Document();
}
sortObject = filterUnwrappedObjects(sortObject, entity);
Document mappedSort = new Document();
for (Map.Entry<String, Object> entry : BsonUtils.asMap(sortObject).entrySet()) {
Field field = createPropertyField(entity, entry.getKey(), mappingContext);
if (field.getProperty() != null && field.getProperty().isUnwrapped()) {
continue;
}
mappedSort.put(field.getMappedKey(), entry.getValue());
}
Document mappedSort = mapFieldsToPropertyNames(sortObject, entity);
mapMetaAttributes(mappedSort, entity, MetaMapping.WHEN_PRESENT);
return mappedSort;
}
@@ -225,13 +213,30 @@ public class QueryMapper {
Assert.notNull(fieldsObject, "FieldsObject must not be null!");
fieldsObject = filterUnwrappedObjects(fieldsObject, entity);
Document mappedFields = getMappedObject(fieldsObject, entity);
Document mappedFields = mapFieldsToPropertyNames(fieldsObject, entity);
mapMetaAttributes(mappedFields, entity, MetaMapping.FORCE);
return mappedFields;
}
private Document mapFieldsToPropertyNames(Document fields, @Nullable MongoPersistentEntity<?> entity) {
if (fields.isEmpty()) {
return new Document();
}
Document target = new Document();
for (Map.Entry<String, Object> entry : BsonUtils.asMap(filterUnwrappedObjects(fields, entity)).entrySet()) {
Field field = createPropertyField(entity, entry.getKey(), mappingContext);
if (field.getProperty() != null && field.getProperty().isUnwrapped()) {
continue;
}
target.put(field.getMappedKey(), entry.getValue());
}
return target;
}
private void mapMetaAttributes(Document source, @Nullable MongoPersistentEntity<?> entity, MetaMapping metaMapping) {
if (entity == null) {

View File

@@ -50,6 +50,7 @@ import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.data.mongodb.core.mapping.FieldType;
import org.springframework.data.mongodb.core.mapping.MongoId;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.TextScore;
@@ -1304,6 +1305,13 @@ public class QueryMapperUnitTests {
assertThat(mapper.getMappedSort(query.getQueryObject(), context.getPersistentEntity(Customer.class))).isEqualTo(new org.bson.Document("address.street", "1007 Mountain Drive"));
}
@Test // GH-3668
void mapStringIdFieldProjection() {
org.bson.Document mappedFields = mapper.getMappedFields(new org.bson.Document("id", 1), context.getPersistentEntity(WithStringId.class));
assertThat(mappedFields).containsEntry("_id", 1);
}
class WithDeepArrayNesting {
List<WithNestedArray> level0;
@@ -1367,6 +1375,12 @@ public class QueryMapperUnitTests {
@Id private String foo;
}
class WithStringId {
@MongoId String id;
String name;
}
class BigIntegerId {
@Id private BigInteger id;