diff --git a/pom.xml b/pom.xml index e43742d5af..264233ba3e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2314-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml index bb7d9f03cc..8f7034915c 100644 --- a/spring-data-mongodb-benchmarks/pom.xml +++ b/spring-data-mongodb-benchmarks/pom.xml @@ -7,7 +7,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2314-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index b32dcba387..4c7f0621df 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2314-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index b611cf01a8..1fd7d9187a 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2314-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java index a9cfbaebf7..6d58b216f8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/QueryMapper.java @@ -318,6 +318,10 @@ protected Document getMappedKeyword(Field property, Keyword keyword) { Object convertedValue = needsAssociationConversion ? convertAssociation(value, property) : getMappedValue(property.with(keyword.getKey()), value); + if(keyword.isSample() && convertedValue instanceof Document) { + return (Document) convertedValue; + } + return new Document(keyword.key, convertedValue); } @@ -325,9 +329,8 @@ protected Document getMappedKeyword(Field property, Keyword keyword) { * Returns the mapped value for the given source object assuming it's a value for the given * {@link MongoPersistentProperty}. * + * @param documentField the key the value will be bound to eventually * @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 */ @Nullable @@ -448,6 +451,10 @@ protected boolean isAssociationConversionNecessary(Field documentField, @Nullabl @SuppressWarnings("unchecked") protected Object convertSimpleOrDocument(Object source, @Nullable MongoPersistentEntity entity) { + if(source instanceof Example) { + return exampleMapper.getMappedExample((Example)source, entity); + } + if (source instanceof List) { return delegateConvertToMongoType(source, entity); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java index c889284348..7d57f16f54 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java @@ -611,7 +611,6 @@ public Criteria elemMatch(Criteria c) { public Criteria alike(Example sample) { criteria.put("$example", sample); - this.criteriaChain.add(this); return this; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java index 647f93a918..ae899d0707 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/QueryByExampleTests.java @@ -15,13 +15,11 @@ */ package org.springframework.data.mongodb.core; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.assertj.core.api.Assertions.*; import lombok.EqualsAndHashCode; import lombok.ToString; -import java.net.UnknownHostException; import java.util.List; import org.junit.Before; @@ -50,7 +48,7 @@ public class QueryByExampleTests { Person p1, p2, p3; @Before - public void setUp() throws UnknownHostException { + public void setUp() { operations = new MongoTemplate(new MongoClient(), "query-by-example"); operations.remove(new Query(), Person.class); @@ -82,8 +80,7 @@ public void findByExampleShouldWorkForSimpleProperty() { Query query = new Query(new Criteria().alike(Example.of(sample))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(2)); - assertThat(result, hasItems(p1, p3)); + assertThat(result).containsExactlyInAnyOrder(p1, p3); } @Test // DATAMONGO-1245 @@ -96,8 +93,7 @@ public void findByExampleShouldWorkForMultipleProperties() { Query query = new Query(new Criteria().alike(Example.of(sample))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(1)); - assertThat(result, hasItem(p3)); + assertThat(result).containsExactly(p3); } @Test // DATAMONGO-1245 @@ -112,8 +108,7 @@ public void findByExampleShouldWorkForIdProperty() { Query query = new Query(new Criteria().alike(Example.of(sample))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(1)); - assertThat(result, hasItem(p4)); + assertThat(result).containsExactly(p4); } @Test // DATAMONGO-1245 @@ -126,7 +121,7 @@ public void findByExampleShouldReturnEmptyListIfNotMatching() { Query query = new Query(new Criteria().alike(Example.of(sample))); List result = operations.find(query, Person.class); - assertThat(result, is(empty())); + assertThat(result).isEmpty(); } @Test // DATAMONGO-1245 @@ -137,8 +132,7 @@ public void findByExampleShouldReturnEverythingWhenSampleIsEmpty() { Query query = new Query(new Criteria().alike(Example.of(sample))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(3)); - assertThat(result, hasItems(p1, p2, p3)); + assertThat(result).containsExactlyInAnyOrder(p1, p2, p3); } @Test // DATAMONGO-1245 @@ -150,7 +144,7 @@ public void findByExampleWithCriteria() { Query query = new Query(new Criteria().alike(Example.of(sample)).and("firstname").regex("^ary*")); List result = operations.find(query, Person.class); - assertThat(result.size(), is(1)); + assertThat(result).hasSize(1); } @Test // DATAMONGO-1459 @@ -163,8 +157,7 @@ public void findsExampleUsingAnyMatch() { Query query = Query.query(Criteria.byExample(Example.of(probe, ExampleMatcher.matchingAny()))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(2)); - assertThat(result, hasItems(p1, p2)); + assertThat(result).containsExactlyInAnyOrder(p1, p2); } @Test // DATAMONGO-1768 @@ -176,7 +169,7 @@ public void typedExampleMatchesNothingIfTypesDoNotMatch() { Query query = new Query(new Criteria().alike(Example.of(probe))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(0)); + assertThat(result).isEmpty(); } @Test // DATAMONGO-1768 @@ -189,8 +182,7 @@ public void exampleIgnoringClassTypeKeyMatchesCorrectly() { new Criteria().alike(Example.of(probe, ExampleMatcher.matching().withIgnorePaths("_class")))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(2)); - assertThat(result, hasItems(p1, p3)); + assertThat(result).containsExactlyInAnyOrder(p1, p3); } @Test // DATAMONGO-1768 @@ -202,8 +194,28 @@ public void untypedExampleMatchesCorrectly() { Query query = new Query(new Criteria().alike(Example.of(probe, UntypedExampleMatcher.matching()))); List result = operations.find(query, Person.class); - assertThat(result, hasSize(2)); - assertThat(result, hasItems(p1, p3)); + assertThat(result).containsExactlyInAnyOrder(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 result = operations.find(query, PersonWrapper.class); + + assertThat(result).containsExactly(source1); } @Document("dramatis-personae") @@ -223,4 +235,13 @@ static class NotAPersonButStillMatchingFields { String firstname, middlename; @Field("last_name") String lastname; } + + @Document("dramatis-personae") + @EqualsAndHashCode + @ToString + static class PersonWrapper { + + @Id String id; + Person child; + } }