Skip to content

Commit 626dfa4

Browse files
christophstroblmp911de
authored andcommitted
DATAMONGO-2003 - Fix derived query using regex pattern with options.
We now consider regex pattern options when using the pattern as a derived finder argument. Original pull request: #570.
1 parent 26c1221 commit 626dfa4

File tree

4 files changed

+64
-22
lines changed

4 files changed

+64
-22
lines changed

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Collection;
2222
import java.util.Iterator;
2323
import java.util.regex.Pattern;
24+
import java.util.regex.Pattern;
2425

2526
import org.slf4j.Logger;
2627
import org.slf4j.LoggerFactory;
@@ -51,7 +52,7 @@
5152

5253
/**
5354
* Custom query creator to create Mongo criterias.
54-
*
55+
*
5556
* @author Oliver Gierke
5657
* @author Thomas Darimont
5758
* @author Christoph Strobl
@@ -69,7 +70,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
6970
/**
7071
* Creates a new {@link MongoQueryCreator} from the given {@link PartTree}, {@link ConvertingParameterAccessor} and
7172
* {@link MappingContext}.
72-
*
73+
*
7374
* @param tree
7475
* @param accessor
7576
* @param context
@@ -82,7 +83,7 @@ public MongoQueryCreator(PartTree tree, ConvertingParameterAccessor accessor,
8283
/**
8384
* Creates a new {@link MongoQueryCreator} from the given {@link PartTree}, {@link ConvertingParameterAccessor} and
8485
* {@link MappingContext}.
85-
*
86+
*
8687
* @param tree
8788
* @param accessor
8889
* @param context
@@ -164,7 +165,7 @@ protected Query complete(Criteria criteria, Sort sort) {
164165

165166
/**
166167
* Populates the given {@link CriteriaDefinition} depending on the {@link Part} given.
167-
*
168+
*
168169
* @param part
169170
* @param property
170171
* @param criteria
@@ -206,7 +207,9 @@ private Criteria from(Part part, MongoPersistentProperty property, Criteria crit
206207
case NOT_CONTAINING:
207208
return createContainingCriteria(part, property, criteria.not(), parameters);
208209
case REGEX:
209-
return criteria.regex(parameters.next().toString());
210+
211+
Object param = parameters.next();
212+
return param instanceof Pattern ? criteria.regex((Pattern) param) : criteria.regex(param.toString());
210213
case EXISTS:
211214
return criteria.exists((Boolean) parameters.next());
212215
case TRUE:
@@ -272,7 +275,7 @@ private boolean isSimpleComparisionPossible(Part part) {
272275

273276
/**
274277
* Creates and extends the given criteria with a like-regex if necessary.
275-
*
278+
*
276279
* @param part
277280
* @param property
278281
* @param criteria
@@ -314,7 +317,7 @@ private Criteria createLikeRegexCriteriaOrThrow(Part part, MongoPersistentProper
314317
* If the target property of the comparison is of type String, then the operator checks for match using regular
315318
* expression. If the target property of the comparison is a {@link Collection} then the operator evaluates to true if
316319
* it finds an exact match within any member of the {@link Collection}.
317-
*
320+
*
318321
* @param part
319322
* @param property
320323
* @param criteria
@@ -333,7 +336,7 @@ private Criteria createContainingCriteria(Part part, MongoPersistentProperty pro
333336

334337
/**
335338
* Creates an appropriate like-regex and appends it to the given criteria.
336-
*
339+
*
337340
* @param criteria
338341
* @param part
339342
* @param value
@@ -368,7 +371,7 @@ private String toRegexOptions(Part part) {
368371

369372
/**
370373
* Returns the next element from the given {@link Iterator} expecting it to be of a certain type.
371-
*
374+
*
372375
* @param <T>
373376
* @param iterator
374377
* @param type

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Arrays;
2525
import java.util.HashSet;
2626
import java.util.List;
27+
import java.util.regex.Pattern;
2728
import java.util.stream.Collectors;
2829
import java.util.stream.Stream;
2930

@@ -63,7 +64,7 @@
6364

6465
/**
6566
* Base class for tests for {@link PersonRepository}.
66-
*
67+
*
6768
* @author Oliver Gierke
6869
* @author Thomas Darimont
6970
* @author Christoph Strobl
@@ -1166,4 +1167,18 @@ public void deletesPersonsByFirstname() {
11661167

11671168
assertThat(repository.countByThePersonsFirstname("Dave"), is(0L));
11681169
}
1170+
1171+
@Test // DATAMONGO-2003
1172+
public void findByRegexWithPattern() {
1173+
assertThat(repository.findByFirstnameRegex(Pattern.compile(alicia.getFirstname())), hasSize(1));
1174+
}
1175+
1176+
@Test // DATAMONGO-2003
1177+
public void findByRegexWithPatternAndOptions() {
1178+
1179+
String fn = alicia.getFirstname().toUpperCase();
1180+
1181+
assertThat(repository.findByFirstnameRegex(Pattern.compile(fn)), hasSize(0));
1182+
assertThat(repository.findByFirstnameRegex(Pattern.compile(fn, Pattern.CASE_INSENSITIVE)), hasSize(1));
1183+
}
11691184
}

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Collection;
1919
import java.util.Date;
2020
import java.util.List;
21+
import java.util.regex.Pattern;
2122
import java.util.stream.Stream;
2223

2324
import org.springframework.data.domain.Page;
@@ -38,7 +39,7 @@
3839

3940
/**
4041
* Sample repository managing {@link Person} entities.
41-
*
42+
*
4243
* @author Oliver Gierke
4344
* @author Thomas Darimont
4445
* @author Christoph Strobl
@@ -49,7 +50,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
4950

5051
/**
5152
* Returns all {@link Person}s with the given lastname.
52-
*
53+
*
5354
* @param lastname
5455
* @return
5556
*/
@@ -61,7 +62,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
6162

6263
/**
6364
* Returns all {@link Person}s with the given lastname ordered by their firstname.
64-
*
65+
*
6566
* @param lastname
6667
* @return
6768
*/
@@ -70,7 +71,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
7071
/**
7172
* Returns the {@link Person}s with the given firstname. Uses {@link Query} annotation to define the query to be
7273
* executed.
73-
*
74+
*
7475
* @param firstname
7576
* @return
7677
*/
@@ -83,7 +84,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
8384

8485
/**
8586
* Returns all {@link Person}s with a firstname matching the given one (*-wildcard supported).
86-
*
87+
*
8788
* @param firstname
8889
* @return
8990
*/
@@ -110,7 +111,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
110111

111112
/**
112113
* Returns a page of {@link Person}s with a lastname mathing the given one (*-wildcards supported).
113-
*
114+
*
114115
* @param lastname
115116
* @param pageable
116117
* @return
@@ -122,15 +123,15 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
122123

123124
/**
124125
* Returns all {@link Person}s with a firstname contained in the given varargs.
125-
*
126+
*
126127
* @param firstnames
127128
* @return
128129
*/
129130
List<Person> findByFirstnameIn(String... firstnames);
130131

131132
/**
132133
* Returns all {@link Person}s with a firstname not contained in the given collection.
133-
*
134+
*
134135
* @param firstnames
135136
* @return
136137
*/
@@ -140,7 +141,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
140141

141142
/**
142143
* Returns all {@link Person}s with an age between the two given values.
143-
*
144+
*
144145
* @param from
145146
* @param to
146147
* @return
@@ -149,15 +150,15 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
149150

150151
/**
151152
* Returns the {@link Person} with the given {@link Address} as shipping address.
152-
*
153+
*
153154
* @param address
154155
* @return
155156
*/
156157
Person findByShippingAddresses(Address address);
157158

158159
/**
159160
* Returns all {@link Person}s with the given {@link Address}.
160-
*
161+
*
161162
* @param address
162163
* @return
163164
*/
@@ -325,4 +326,6 @@ Page<Person> findByCustomQueryLastnameAndAddressStreetInList(String lastname, Li
325326
*/
326327
@DeleteQuery("{ 'firstname' : ?0 }") // DATAMONGO-1539
327328
void deleteByThePersonsFirstname(String firstname);
329+
330+
List<Person> findByFirstnameRegex(Pattern pattern);
328331
}

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424

2525
import java.lang.reflect.Method;
2626
import java.util.List;
27+
import java.util.regex.Pattern;
2728

29+
import org.bson.Document;
2830
import org.bson.types.ObjectId;
2931
import org.junit.Before;
3032
import org.junit.Rule;
@@ -64,7 +66,7 @@
6466

6567
/**
6668
* Unit test for {@link MongoQueryCreator}.
67-
*
69+
*
6870
* @author Oliver Gierke
6971
* @author Thomas Darimont
7072
* @author Christoph Strobl
@@ -627,6 +629,25 @@ public void queryShouldThrowExceptionWhenArgumentDoesNotMatchDeclaration() {
627629
new MongoQueryCreator(tree, accessor, context).createQuery();
628630
}
629631

632+
@Test // DATAMONGO-2003
633+
public void createsRegexQueryForPatternCorrectly() throws Exception {
634+
635+
PartTree tree = new PartTree("findByFirstNameRegex", Person.class);
636+
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, Pattern.compile(".*")), context);
637+
638+
assertThat(creator.createQuery(), is(query(where("firstName").regex(".*"))));
639+
}
640+
641+
@Test // DATAMONGO-2003
642+
public void createsRegexQueryForPatternWithOptionsCorrectly() throws Exception {
643+
644+
Pattern pattern = Pattern.compile(".*", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
645+
646+
PartTree tree = new PartTree("findByFirstNameRegex", Person.class);
647+
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, pattern), context);
648+
assertThat(creator.createQuery(), is(query(where("firstName").regex(".*", "iu"))));
649+
}
650+
630651
interface PersonRepository extends Repository<Person, Long> {
631652

632653
List<Person> findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname);

0 commit comments

Comments
 (0)