Browse Source

Avoid nested Document conversion to primitive types for fields with an explicit write target.

We now no longer attempt to convert query Documents into primitive types to avoid e.g. Document to String conversion.

Closes: #3783
Original Pull Request: #3797
pull/3802/head
Mark Paluch 4 years ago committed by Christoph Strobl
parent
commit
f24e8e5361
  1. 3
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java
  2. 31
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java

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

@ -778,7 +778,8 @@ public class QueryMapper { @@ -778,7 +778,8 @@ public class QueryMapper {
@Nullable
private Object applyFieldTargetTypeHintToValue(Field documentField, @Nullable Object value) {
if (value == null || documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()) {
if (value == null || documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()
|| value instanceof Document || value instanceof DBObject) {
return value;
}

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

@ -33,8 +33,7 @@ import org.bson.types.Code; @@ -33,8 +33,7 @@ import org.bson.types.Code;
import org.bson.types.ObjectId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
@ -83,9 +82,12 @@ public class QueryMapperUnitTests { @@ -83,9 +82,12 @@ public class QueryMapperUnitTests {
@BeforeEach
void beforeEach() {
MongoCustomConversions conversions = new MongoCustomConversions();
this.context = new MongoMappingContext();
this.context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
this.converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, context);
this.converter.setCustomConversions(conversions);
this.converter.afterPropertiesSet();
this.mapper = new QueryMapper(converter);
@ -1335,6 +1337,25 @@ public class QueryMapperUnitTests { @@ -1335,6 +1337,25 @@ public class QueryMapperUnitTests {
assertThat(mappedFields).containsEntry("_id", 1);
}
@Test // GH-3783
void retainsId$InWithStringArray() {
org.bson.Document mappedQuery = mapper.getMappedObject(
org.bson.Document.parse("{ _id : { $in: [\"5b8bedceb1e0bfc07b008828\"]}}"),
context.getPersistentEntity(WithExplicitStringId.class));
assertThat(mappedQuery.get("_id")).isEqualTo(org.bson.Document.parse("{ $in: [\"5b8bedceb1e0bfc07b008828\"]}"));
}
@Test // GH-3783
void mapsId$InInToObjectIds() {
org.bson.Document mappedQuery = mapper.getMappedObject(
org.bson.Document.parse("{ _id : { $in: [\"5b8bedceb1e0bfc07b008828\"]}}"),
context.getPersistentEntity(ClassWithDefaultId.class));
assertThat(mappedQuery.get("_id"))
.isEqualTo(org.bson.Document.parse("{ $in: [ {$oid: \"5b8bedceb1e0bfc07b008828\" } ]}"));
}
class WithDeepArrayNesting {
List<WithNestedArray> level0;
@ -1404,6 +1425,12 @@ public class QueryMapperUnitTests { @@ -1404,6 +1425,12 @@ public class QueryMapperUnitTests {
String name;
}
class WithExplicitStringId {
@MongoId(FieldType.STRING) String id;
String name;
}
class BigIntegerId {
@Id private BigInteger id;

Loading…
Cancel
Save