Description
When I use the Criteria class to construct a query with a regex(using mongoTemplate.find() ), the query does not return a result using version 4.2.0+, whereas the same code, using version 4.1.0, returns the result correctly.
Example: criteria.regex("^abc").
I followed the source code to try to find the cause of the problem. Here's what I found:
When querying in mongoTemplate's doFind
method, the query conditions passed in are transformed as follows: Document mappedQuery = queryContext.getMappedQuery(entity);
. In versions of spring-data-mongo 4.2+ (spring-core 6.1.0+), the transformed mappedQuery will convert java.util.regex.Pattern
to java.lang.String
, which prevents it from entering the mongo-driver's PatternCodec
. Consequently, the resulting mongo query condition changes from { "$regex": "^abc" }
to "^abc"
, meaning it no longer uses "regex" for regex queries but instead becomes an "equal" comparison query.
The root cause of this issue lies in the fact that in spring-core 6.1.0+ versions, a PR was merged (spring-core PR-24311) that added a pattern-to-string converter to DefaultConversionService
in spring-core, namely the ObjectToStringConverter
. In the QueryMapper#applyFieldTargetTypeHintToValue
method of spring-data-mongo, the conversionService's canConvert(...)
method is called to determine if a Pattern can be converted to a String. In previous versions, without this converter, canConvert(...)
would return false
, indicating that conversion was not possible and thus returning java.util.regex.Pattern
as is.
However, in spring-core 6.1.0+ versions, with the presence of this converter, canConvert(...)
now returns true, indicating conversion is possible. As a result, ObjectToStringConverter
is invoked to convert java.util.regex.Pattern
to String, leading to the aforementioned bug.
