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.
This commit is contained in:
Christoph Strobl
2019-07-04 10:14:44 +02:00
committed by Mark Paluch
parent f42cb1e2f0
commit d7107d49bf
3 changed files with 51 additions and 24 deletions

View File

@@ -307,6 +307,10 @@ public class QueryMapper {
Object convertedValue = needsAssociationConversion ? convertAssociation(value, property) Object convertedValue = needsAssociationConversion ? convertAssociation(value, property)
: getMappedValue(property.with(keyword.getKey()), value); : getMappedValue(property.with(keyword.getKey()), value);
if(keyword.isSample() && convertedValue instanceof Document) {
return (Document) convertedValue;
}
return new Document(keyword.key, convertedValue); return new Document(keyword.key, convertedValue);
} }
@@ -314,9 +318,8 @@ public class QueryMapper {
* Returns the mapped value for the given source object assuming it's a value for the given * Returns the mapped value for the given source object assuming it's a value for the given
* {@link MongoPersistentProperty}. * {@link MongoPersistentProperty}.
* *
* @param documentField the key the value will be bound to eventually
* @param value the source object to be mapped * @param value the source object to be mapped
* @param property the property the value is a value for
* @param newKey the key the value will be bound to eventually
* @return * @return
*/ */
@Nullable @Nullable
@@ -423,6 +426,10 @@ public class QueryMapper {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersistentEntity<?> entity) { protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersistentEntity<?> entity) {
if(source instanceof Example) {
return exampleMapper.getMappedExample((Example)source, entity);
}
if (source instanceof List) { if (source instanceof List) {
return delegateConvertToMongoType(source, entity); return delegateConvertToMongoType(source, entity);
} }

View File

@@ -597,7 +597,6 @@ public class Criteria implements CriteriaDefinition {
public Criteria alike(Example<?> sample) { public Criteria alike(Example<?> sample) {
criteria.put("$example", sample); criteria.put("$example", sample);
this.criteriaChain.add(this);
return this; return this;
} }

View File

@@ -15,13 +15,11 @@
*/ */
package org.springframework.data.mongodb.core; package org.springframework.data.mongodb.core;
import static org.hamcrest.Matchers.*; import static org.assertj.core.api.Assertions.*;
import static org.junit.Assert.*;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import java.net.UnknownHostException;
import java.util.List; import java.util.List;
import org.junit.Before; import org.junit.Before;
@@ -50,7 +48,7 @@ public class QueryByExampleTests {
Person p1, p2, p3; Person p1, p2, p3;
@Before @Before
public void setUp() throws UnknownHostException { public void setUp() {
operations = new MongoTemplate(new MongoClient(), "query-by-example"); operations = new MongoTemplate(new MongoClient(), "query-by-example");
operations.remove(new Query(), Person.class); operations.remove(new Query(), Person.class);
@@ -82,8 +80,7 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(sample))); Query query = new Query(new Criteria().alike(Example.of(sample)));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(2)); assertThat(result).containsExactlyInAnyOrder(p1, p3);
assertThat(result, hasItems(p1, p3));
} }
@Test // DATAMONGO-1245 @Test // DATAMONGO-1245
@@ -96,8 +93,7 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(sample))); Query query = new Query(new Criteria().alike(Example.of(sample)));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(1)); assertThat(result).containsExactly(p3);
assertThat(result, hasItem(p3));
} }
@Test // DATAMONGO-1245 @Test // DATAMONGO-1245
@@ -112,8 +108,7 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(sample))); Query query = new Query(new Criteria().alike(Example.of(sample)));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(1)); assertThat(result).containsExactly(p4);
assertThat(result, hasItem(p4));
} }
@Test // DATAMONGO-1245 @Test // DATAMONGO-1245
@@ -126,7 +121,7 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(sample))); Query query = new Query(new Criteria().alike(Example.of(sample)));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, is(empty())); assertThat(result).isEmpty();
} }
@Test // DATAMONGO-1245 @Test // DATAMONGO-1245
@@ -137,8 +132,7 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(sample))); Query query = new Query(new Criteria().alike(Example.of(sample)));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(3)); assertThat(result).containsExactlyInAnyOrder(p1, p2, p3);
assertThat(result, hasItems(p1, p2, p3));
} }
@Test // DATAMONGO-1245 @Test // DATAMONGO-1245
@@ -150,7 +144,7 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(sample)).and("firstname").regex("^ary*")); Query query = new Query(new Criteria().alike(Example.of(sample)).and("firstname").regex("^ary*"));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result.size(), is(1)); assertThat(result).hasSize(1);
} }
@Test // DATAMONGO-1459 @Test // DATAMONGO-1459
@@ -163,8 +157,7 @@ public class QueryByExampleTests {
Query query = Query.query(Criteria.byExample(Example.of(probe, ExampleMatcher.matchingAny()))); Query query = Query.query(Criteria.byExample(Example.of(probe, ExampleMatcher.matchingAny())));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(2)); assertThat(result).containsExactlyInAnyOrder(p1, p2);
assertThat(result, hasItems(p1, p2));
} }
@Test // DATAMONGO-1768 @Test // DATAMONGO-1768
@@ -176,7 +169,7 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(probe))); Query query = new Query(new Criteria().alike(Example.of(probe)));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(0)); assertThat(result).isEmpty();
} }
@Test // DATAMONGO-1768 @Test // DATAMONGO-1768
@@ -189,8 +182,7 @@ public class QueryByExampleTests {
new Criteria().alike(Example.of(probe, ExampleMatcher.matching().withIgnorePaths("_class")))); new Criteria().alike(Example.of(probe, ExampleMatcher.matching().withIgnorePaths("_class"))));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(2)); assertThat(result).containsExactlyInAnyOrder(p1, p3);
assertThat(result, hasItems(p1, p3));
} }
@Test // DATAMONGO-1768 @Test // DATAMONGO-1768
@@ -202,8 +194,28 @@ public class QueryByExampleTests {
Query query = new Query(new Criteria().alike(Example.of(probe, UntypedExampleMatcher.matching()))); Query query = new Query(new Criteria().alike(Example.of(probe, UntypedExampleMatcher.matching())));
List<Person> result = operations.find(query, Person.class); List<Person> result = operations.find(query, Person.class);
assertThat(result, hasSize(2)); assertThat(result).containsExactlyInAnyOrder(p1, p3);
assertThat(result, hasItems(p1, p3)); }
@Test // DATAMONGO-2314
public void alikeShouldWorkOnNestedProperties() {
PersonWrapper source1 = new PersonWrapper();
source1.id = "with-child-doc-1";
source1.child = p1;
PersonWrapper source2 = new PersonWrapper();
source2.id = "with-child-doc-2";
source2.child = p2;
operations.save(source1);
operations.save(source2);
Query query = new Query(
new Criteria("child").alike(Example.of(p1, ExampleMatcher.matching().withIgnorePaths("_class"))));
List<PersonWrapper> result = operations.find(query, PersonWrapper.class);
assertThat(result).containsExactly(source1);
} }
@Document("dramatis-personae") @Document("dramatis-personae")
@@ -223,4 +235,13 @@ public class QueryByExampleTests {
String firstname, middlename; String firstname, middlename;
@Field("last_name") String lastname; @Field("last_name") String lastname;
} }
@Document("dramatis-personae")
@EqualsAndHashCode
@ToString
static class PersonWrapper {
@Id String id;
Person child;
}
} }