Skip to content

Commit 6b7ac32

Browse files
christophstroblmp911de
authored andcommitted
Fix property value conversion for $in clauses.
This commit fixes an issue where a property value converter is not applied if the query is using an $in clause that compares the value against a collection of potential candidates. Original pull request: #4324 Closes #4080
1 parent 6004c9a commit 6b7ac32

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

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

+14-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@
2727
import org.bson.Document;
2828
import org.bson.conversions.Bson;
2929
import org.bson.types.ObjectId;
30-
3130
import org.springframework.core.convert.ConversionService;
3231
import org.springframework.core.convert.converter.Converter;
3332
import org.springframework.data.annotation.Reference;
33+
import org.springframework.data.convert.PropertyValueConverter;
34+
import org.springframework.data.convert.ValueConversionContext;
3435
import org.springframework.data.domain.Example;
3536
import org.springframework.data.mapping.Association;
3637
import org.springframework.data.mapping.MappingException;
@@ -438,9 +439,18 @@ protected Object getMappedValue(Field documentField, Object sourceValue) {
438439

439440
if (documentField.getProperty() != null
440441
&& converter.getCustomConversions().getPropertyValueConversions().hasValueConverter(documentField.getProperty())) {
441-
return converter.getCustomConversions().getPropertyValueConversions()
442-
.getValueConverter(documentField.getProperty())
443-
.write(value, new MongoConversionContext(documentField.getProperty(), converter));
442+
443+
MongoConversionContext conversionContext = new MongoConversionContext(documentField.getProperty(), converter);
444+
PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter = converter
445+
.getCustomConversions().getPropertyValueConversions().getValueConverter(documentField.getProperty());
446+
447+
/* might be an $in clause with multiple entries */
448+
if (!documentField.getProperty().isCollectionLike() && sourceValue instanceof Collection<?>) {
449+
Collection<?> collection = (Collection<?>) sourceValue;
450+
return collection.stream().map(it -> valueConverter.write(it, conversionContext)).collect(Collectors.toList());
451+
}
452+
453+
return valueConverter.write(value, conversionContext);
444454
}
445455

446456
if (documentField.isIdField() && !documentField.isAssociation()) {

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

+12-3
Original file line numberDiff line numberDiff line change
@@ -1453,14 +1453,23 @@ void mapStringIdFieldProjection() {
14531453
assertThat(mappedQuery.get("_id"))
14541454
.isEqualTo(org.bson.Document.parse("{ $in: [ {$oid: \"5b8bedceb1e0bfc07b008828\" } ]}"));
14551455
}
1456-
1456+
14571457
@Test // GH-3596
14581458
void considersValueConverterWhenPresent() {
14591459

14601460
org.bson.Document mappedObject = mapper.getMappedObject(new org.bson.Document("text", "value"), context.getPersistentEntity(WithPropertyValueConverter.class));
14611461
assertThat(mappedObject).isEqualTo(new org.bson.Document("text", "eulav"));
14621462
}
14631463

1464+
@Test // GH-4080
1465+
void convertsListOfValuesForPropertyThatHasValueConverterButIsNotCollectionLikeOneByOne() {
1466+
1467+
org.bson.Document mappedObject = mapper.getMappedObject(query(where("text").in("spring", "data")).getQueryObject(),
1468+
context.getPersistentEntity(WithPropertyValueConverter.class));
1469+
1470+
assertThat(mappedObject).isEqualTo("{ 'text' : { $in : ['gnirps', 'atad'] } }");
1471+
}
1472+
14641473
class WithDeepArrayNesting {
14651474

14661475
List<WithNestedArray> level0;
@@ -1739,9 +1748,9 @@ static class Customer {
17391748
static class MyAddress {
17401749
private String street;
17411750
}
1742-
1751+
17431752
static class WithPropertyValueConverter {
1744-
1753+
17451754
@ValueConverter(ReversingValueConverter.class)
17461755
String text;
17471756
}

0 commit comments

Comments
 (0)