Skip to content

Commit 6178285

Browse files
christophstroblmp911de
authored andcommitted
DATAMONGO-2314 - Fix query by example on nested properties.
This fix allows using alike on nested properties. new Criteria("nested").alike(Example.of(probe, matching().withIgnorePaths("_class")))); Switch tests to AssertJ. Original pull request: #771.
1 parent c0a2266 commit 6178285

File tree

3 files changed

+51
-24
lines changed

3 files changed

+51
-24
lines changed

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

+9-2
Original file line numberDiff line numberDiff line change
@@ -318,16 +318,19 @@ protected Document getMappedKeyword(Field property, Keyword keyword) {
318318
Object convertedValue = needsAssociationConversion ? convertAssociation(value, property)
319319
: getMappedValue(property.with(keyword.getKey()), value);
320320

321+
if(keyword.isSample() && convertedValue instanceof Document) {
322+
return (Document) convertedValue;
323+
}
324+
321325
return new Document(keyword.key, convertedValue);
322326
}
323327

324328
/**
325329
* Returns the mapped value for the given source object assuming it's a value for the given
326330
* {@link MongoPersistentProperty}.
327331
*
332+
* @param documentField the key the value will be bound to eventually
328333
* @param value the source object to be mapped
329-
* @param property the property the value is a value for
330-
* @param newKey the key the value will be bound to eventually
331334
* @return
332335
*/
333336
@Nullable
@@ -448,6 +451,10 @@ protected boolean isAssociationConversionNecessary(Field documentField, @Nullabl
448451
@SuppressWarnings("unchecked")
449452
protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersistentEntity<?> entity) {
450453

454+
if(source instanceof Example) {
455+
return exampleMapper.getMappedExample((Example)source, entity);
456+
}
457+
451458
if (source instanceof List) {
452459
return delegateConvertToMongoType(source, entity);
453460
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,6 @@ public Criteria elemMatch(Criteria c) {
611611
public Criteria alike(Example<?> sample) {
612612

613613
criteria.put("$example", sample);
614-
this.criteriaChain.add(this);
615614
return this;
616615
}
617616

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

+42-21
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@
1515
*/
1616
package org.springframework.data.mongodb.core;
1717

18-
import static org.hamcrest.Matchers.*;
19-
import static org.junit.Assert.*;
18+
import static org.assertj.core.api.Assertions.*;
2019

2120
import lombok.EqualsAndHashCode;
2221
import lombok.ToString;
2322

24-
import java.net.UnknownHostException;
2523
import java.util.List;
2624

2725
import org.junit.Before;
@@ -50,7 +48,7 @@ public class QueryByExampleTests {
5048
Person p1, p2, p3;
5149

5250
@Before
53-
public void setUp() throws UnknownHostException {
51+
public void setUp() {
5452

5553
operations = new MongoTemplate(new MongoClient(), "query-by-example");
5654
operations.remove(new Query(), Person.class);
@@ -82,8 +80,7 @@ public void findByExampleShouldWorkForSimpleProperty() {
8280
Query query = new Query(new Criteria().alike(Example.of(sample)));
8381
List<Person> result = operations.find(query, Person.class);
8482

85-
assertThat(result, hasSize(2));
86-
assertThat(result, hasItems(p1, p3));
83+
assertThat(result).containsExactlyInAnyOrder(p1, p3);
8784
}
8885

8986
@Test // DATAMONGO-1245
@@ -96,8 +93,7 @@ public void findByExampleShouldWorkForMultipleProperties() {
9693
Query query = new Query(new Criteria().alike(Example.of(sample)));
9794
List<Person> result = operations.find(query, Person.class);
9895

99-
assertThat(result, hasSize(1));
100-
assertThat(result, hasItem(p3));
96+
assertThat(result).containsExactly(p3);
10197
}
10298

10399
@Test // DATAMONGO-1245
@@ -112,8 +108,7 @@ public void findByExampleShouldWorkForIdProperty() {
112108
Query query = new Query(new Criteria().alike(Example.of(sample)));
113109
List<Person> result = operations.find(query, Person.class);
114110

115-
assertThat(result, hasSize(1));
116-
assertThat(result, hasItem(p4));
111+
assertThat(result).containsExactly(p4);
117112
}
118113

119114
@Test // DATAMONGO-1245
@@ -126,7 +121,7 @@ public void findByExampleShouldReturnEmptyListIfNotMatching() {
126121
Query query = new Query(new Criteria().alike(Example.of(sample)));
127122
List<Person> result = operations.find(query, Person.class);
128123

129-
assertThat(result, is(empty()));
124+
assertThat(result).isEmpty();
130125
}
131126

132127
@Test // DATAMONGO-1245
@@ -137,8 +132,7 @@ public void findByExampleShouldReturnEverythingWhenSampleIsEmpty() {
137132
Query query = new Query(new Criteria().alike(Example.of(sample)));
138133
List<Person> result = operations.find(query, Person.class);
139134

140-
assertThat(result, hasSize(3));
141-
assertThat(result, hasItems(p1, p2, p3));
135+
assertThat(result).containsExactlyInAnyOrder(p1, p2, p3);
142136
}
143137

144138
@Test // DATAMONGO-1245
@@ -150,7 +144,7 @@ public void findByExampleWithCriteria() {
150144
Query query = new Query(new Criteria().alike(Example.of(sample)).and("firstname").regex("^ary*"));
151145

152146
List<Person> result = operations.find(query, Person.class);
153-
assertThat(result.size(), is(1));
147+
assertThat(result).hasSize(1);
154148
}
155149

156150
@Test // DATAMONGO-1459
@@ -163,8 +157,7 @@ public void findsExampleUsingAnyMatch() {
163157
Query query = Query.query(Criteria.byExample(Example.of(probe, ExampleMatcher.matchingAny())));
164158
List<Person> result = operations.find(query, Person.class);
165159

166-
assertThat(result, hasSize(2));
167-
assertThat(result, hasItems(p1, p2));
160+
assertThat(result).containsExactlyInAnyOrder(p1, p2);
168161
}
169162

170163
@Test // DATAMONGO-1768
@@ -176,7 +169,7 @@ public void typedExampleMatchesNothingIfTypesDoNotMatch() {
176169
Query query = new Query(new Criteria().alike(Example.of(probe)));
177170
List<Person> result = operations.find(query, Person.class);
178171

179-
assertThat(result, hasSize(0));
172+
assertThat(result).isEmpty();
180173
}
181174

182175
@Test // DATAMONGO-1768
@@ -189,8 +182,7 @@ public void exampleIgnoringClassTypeKeyMatchesCorrectly() {
189182
new Criteria().alike(Example.of(probe, ExampleMatcher.matching().withIgnorePaths("_class"))));
190183
List<Person> result = operations.find(query, Person.class);
191184

192-
assertThat(result, hasSize(2));
193-
assertThat(result, hasItems(p1, p3));
185+
assertThat(result).containsExactlyInAnyOrder(p1, p3);
194186
}
195187

196188
@Test // DATAMONGO-1768
@@ -202,8 +194,28 @@ public void untypedExampleMatchesCorrectly() {
202194
Query query = new Query(new Criteria().alike(Example.of(probe, UntypedExampleMatcher.matching())));
203195
List<Person> result = operations.find(query, Person.class);
204196

205-
assertThat(result, hasSize(2));
206-
assertThat(result, hasItems(p1, p3));
197+
assertThat(result).containsExactlyInAnyOrder(p1, p3);
198+
}
199+
200+
@Test // DATAMONGO-2314
201+
public void alikeShouldWorkOnNestedProperties() {
202+
203+
PersonWrapper source1 = new PersonWrapper();
204+
source1.id = "with-child-doc-1";
205+
source1.child = p1;
206+
207+
PersonWrapper source2 = new PersonWrapper();
208+
source2.id = "with-child-doc-2";
209+
source2.child = p2;
210+
211+
operations.save(source1);
212+
operations.save(source2);
213+
214+
Query query = new Query(
215+
new Criteria("child").alike(Example.of(p1, ExampleMatcher.matching().withIgnorePaths("_class"))));
216+
List<PersonWrapper> result = operations.find(query, PersonWrapper.class);
217+
218+
assertThat(result).containsExactly(source1);
207219
}
208220

209221
@Document("dramatis-personae")
@@ -223,4 +235,13 @@ static class NotAPersonButStillMatchingFields {
223235
String firstname, middlename;
224236
@Field("last_name") String lastname;
225237
}
238+
239+
@Document("dramatis-personae")
240+
@EqualsAndHashCode
241+
@ToString
242+
static class PersonWrapper {
243+
244+
@Id String id;
245+
Person child;
246+
}
226247
}

0 commit comments

Comments
 (0)