Skip to content

Commit c48b2c6

Browse files
christophstroblmp911de
authored andcommitted
Use exact matching for IN clause with ignore case.
Prior to this change the generated pattern would have matched more entries than it should have. The behavior is now aligned to its counterpart not using the IgnoreCase flag. Closes #4404 Original pull request: #4412
1 parent 3a48a2c commit c48b2c6

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MongoRegexCreator.java

+2
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ public String toRegularExpression(@Nullable String source, @Nullable MatchMode m
107107
* @param source
108108
* @return
109109
* @since 2.2.14
110+
* @deprecated since 4.0.7
110111
*/
112+
@Deprecated(since = "4.0.7", forRemoval = true)
111113
public Object toCaseInsensitiveMatch(Object source) {
112114
return source instanceof String ? new BsonRegularExpression(Pattern.quote((String) source), "i") : source;
113115
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
import org.apache.commons.logging.Log;
2727
import org.apache.commons.logging.LogFactory;
28-
28+
import org.bson.BsonRegularExpression;
2929
import org.springframework.data.domain.Range;
3030
import org.springframework.data.domain.Range.Bound;
3131
import org.springframework.data.domain.Sort;
@@ -390,7 +390,18 @@ private java.util.List<?> nextAsList(Iterator<Object> iterator, Part part) {
390390

391391
Streamable<?> streamable = asStreamable(iterator.next());
392392
if (!isSimpleComparisionPossible(part)) {
393-
streamable = streamable.map(MongoRegexCreator.INSTANCE::toCaseInsensitiveMatch);
393+
394+
MatchMode matchMode = toMatchMode(part.getType());
395+
String regexOptions = toRegexOptions(part);
396+
397+
streamable = streamable.map(it -> {
398+
if (it instanceof String value) {
399+
400+
return new BsonRegularExpression(MongoRegexCreator.INSTANCE.toRegularExpression(value, matchMode),
401+
regexOptions);
402+
}
403+
return it;
404+
});
394405
}
395406

396407
return streamable.toList();
@@ -482,6 +493,7 @@ private static MatchMode toMatchMode(Type type) {
482493
return MatchMode.REGEX;
483494
case NEGATING_SIMPLE_PROPERTY:
484495
case SIMPLE_PROPERTY:
496+
case IN:
485497
return MatchMode.EXACT;
486498
default:
487499
return MatchMode.DEFAULT;

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -1451,9 +1451,16 @@ void findByUnwrapped() {
14511451
assertThat(result.get(0).getId().equals(bart.getId()));
14521452
}
14531453

1454-
@Test // GH-3395
1454+
@Test // GH-3395, GH-4404
14551455
void caseInSensitiveInClause() {
1456+
14561457
assertThat(repository.findByLastnameIgnoreCaseIn("bEAuFoRd", "maTTheWs")).hasSize(3);
1458+
1459+
repository.save(new Person("the-first", "The First"));
1460+
repository.save(new Person("the-first-one", "The First One"));
1461+
repository.save(new Person("the-second", "The Second"));
1462+
1463+
assertThat(repository.findByLastnameIgnoreCaseIn("tHE fIRsT")).hasSize(1);
14571464
}
14581465

14591466
@Test // GH-3395

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.List;
2626
import java.util.regex.Pattern;
2727

28+
import org.bson.BsonRegularExpression;
2829
import org.bson.Document;
2930
import org.bson.types.ObjectId;
3031
import org.junit.jupiter.api.BeforeEach;
@@ -273,6 +274,17 @@ void createsQueryWithFindByIgnoreCaseCorrectly() {
273274
assertThat(query).isEqualTo(query(where("firstName").regex("^dave$", "i")));
274275
}
275276

277+
@Test // GH-4404
278+
void createsQueryWithFindByInClauseHavingIgnoreCaseCorrectly() {
279+
280+
PartTree tree = new PartTree("findAllByFirstNameInIgnoreCase", Person.class);
281+
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, List.of("da've", "carter")), context);
282+
283+
Query query = creator.createQuery();
284+
assertThat(query).isEqualTo(query(where("firstName")
285+
.in(List.of(new BsonRegularExpression("^\\Qda've\\E$", "i"), new BsonRegularExpression("^carter$", "i")))));
286+
}
287+
276288
@Test // DATAMONGO-770
277289
void createsQueryWithFindByNotIgnoreCaseCorrectly() {
278290

0 commit comments

Comments
 (0)