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 bba8054cc..32738d8b0 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 @@ -815,6 +815,11 @@ public class QueryMapper { */ @Nullable public Object convertId(@Nullable Object id, Class targetType) { + + if (!SpecialTypeTreatment.INSTANCE.isConversionCandidate(id)) { + return id; + } + return converter.convertId(id, targetType); } @@ -876,8 +881,8 @@ public class QueryMapper { private Object applyFieldTargetTypeHintToValue(Field documentField, @Nullable Object value) { if (value == null || documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget() - || value instanceof Document || value instanceof DBObject || value instanceof Pattern - || value instanceof BsonRegularExpression) { + || value instanceof Document || value instanceof DBObject + || !SpecialTypeTreatment.INSTANCE.isConversionCandidate(value)) { return value; } @@ -1604,4 +1609,22 @@ public class QueryMapper { throw new IllegalStateException("No enclosing property source available"); } } + + /* + * Types that must not be converted + */ + enum SpecialTypeTreatment { + + INSTANCE; + + private final Set> types = Set.of(Pattern.class, BsonRegularExpression.class); + + boolean isConversionCandidate(@Nullable Object value) { + if (value == null) { + return false; + } + + return !types.contains(value.getClass()); + } + } } 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 5cd84120a..d08f68dbd 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 @@ -1101,6 +1101,21 @@ public class QueryMapperUnitTests { assertThat(document.get("text")).isInstanceOf(BsonRegularExpression.class); } + @Test // GH-4674 + void shouldRetainRegexPatternForIdProperty() { + + org.bson.Document javaRegex = mapper.getMappedObject(query(where("id").regex("^1234$")).getQueryObject(), + context.getPersistentEntity(WithStringId.class)); + + assertThat(javaRegex.get("_id")).isInstanceOf(Pattern.class); + + org.bson.Document bsonRegex = mapper.getMappedObject( + query(where("id").regex(new BsonRegularExpression("^1234$"))).getQueryObject(), + context.getPersistentEntity(WithStringId.class)); + + assertThat(bsonRegex.get("_id")).isInstanceOf(BsonRegularExpression.class); + } + @Test // DATAMONGO-2339 void findByIdUsesMappedIdFieldNameWithUnderscoreCorrectly() {