From 05c2045e45f5309c4e8f48c36142d7aea38db355 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 12 Mar 2012 15:46:33 +0100 Subject: [PATCH] DATAMONGO-347 - Derived repository queries now correctly resolve referenced DBRef properties. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added toDBRef(…) method to MongoWriter to be able to create a DBRef representation of an object. Polished DBRef creation implementation inside MappingMongoConverter. Removed collection and id attributes from @DBRef annotation as they have neither been documented nor used so far. Refactored MongoQueryCreator to be aware of the property and convert the given value into a DBRef if necessary. --- .../core/convert/MappingMongoConverter.java | 41 ++++++++++++----- .../mongodb/core/convert/MongoWriter.java | 14 +++++- .../data/mongodb/core/mapping/DBRef.java | 20 +++++---- .../query/ConvertingParameterAccessor.java | 33 +++++++------- .../repository/query/MongoQueryCreator.java | 40 +++++++++-------- .../core/MongoOperationsUnitTests.java | 5 +++ .../MappingMongoConverterUnitTests.java | 44 +++++++++++++++++++ ...tractPersonRepositoryIntegrationTests.java | 28 +++++++++++- .../data/mongodb/repository/Person.java | 4 ++ .../mongodb/repository/PersonRepository.java | 2 + .../data/mongodb/repository/User.java | 27 ++++++++++++ .../query/MongoQueryCreatorUnitTests.java | 24 +++++++++- 12 files changed, 223 insertions(+), 59 deletions(-) create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/User.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index ea11e714f..0bdbf9364 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 by the original author(s). + * Copyright 2011-2012 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -265,6 +265,22 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return result; } + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.convert.MongoWriter#toDBRef(java.lang.Object, org.springframework.data.mongodb.core.mapping.MongoPersistentProperty) + */ + public DBRef toDBRef(Object object, MongoPersistentProperty referingProperty) { + + org.springframework.data.mongodb.core.mapping.DBRef annotation = null; + + if (referingProperty != null) { + annotation = referingProperty.getDBRef(); + Assert.isTrue(annotation != null, "The referenced property has to be mapped with @DBRef!"); + } + + return createDBRef(object, annotation); + } + /** * Root entry method into write conversion. Adds a type discriminator to the {@link DBObject}. Shouldn't be called for * nested conversions. @@ -658,12 +674,20 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App protected DBRef createDBRef(Object target, org.springframework.data.mongodb.core.mapping.DBRef dbref) { + Assert.notNull(target); + MongoPersistentEntity targetEntity = mappingContext.getPersistentEntity(target.getClass()); - if (null == targetEntity || null == targetEntity.getIdProperty()) { - return null; + + if (null == targetEntity) { + throw new MappingException("No mapping metadata found for " + target.getClass()); } MongoPersistentProperty idProperty = targetEntity.getIdProperty(); + + if (idProperty == null) { + throw new MappingException("No id property found on class " + targetEntity.getType()); + } + BeanWrapper, Object> wrapper = BeanWrapper.create(target, conversionService); Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly); @@ -671,15 +695,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App throw new MappingException("Cannot create a reference to an object with a NULL id."); } - String collection = dbref.collection(); - if ("".equals(collection)) { - collection = targetEntity.getCollection(); - } + DB db = mongoDbFactory.getDb(); + db = dbref != null && StringUtils.hasText(dbref.db()) ? mongoDbFactory.getDb(dbref.db()) : db; - String dbname = dbref.db(); - DB db = StringUtils.hasText(dbname) ? mongoDbFactory.getDb(dbname) : mongoDbFactory.getDb(); - - return new DBRef(db, collection, idMapper.convertId(id)); + return new DBRef(db, targetEntity.getCollection(), idMapper.convertId(id)); } protected Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator eval, diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java index 47e58693c..4c04452bb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 the original author or authors. + * Copyright 2010-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,10 @@ package org.springframework.data.mongodb.core.convert; import org.springframework.data.convert.EntityWriter; +import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import com.mongodb.DBObject; +import com.mongodb.DBRef; /** * A MongoWriter is responsible for converting an object of type T to the native MongoDB representation DBObject. @@ -37,4 +39,14 @@ public interface MongoWriter extends EntityWriter { * @return */ Object convertToMongoType(Object obj); + + /** + * Creates a {@link DBRef} to refer to the given object. + * + * @param object the object to create a {@link DBRef} to link to. The object's type has to carry an id attribute. + * @param referingProperty the client-side property referring to the object which might carry additional metadata for + * the {@link DBRef} object to create. Can be {@literal null}. + * @return will never be {@literal null}. + */ + DBRef toDBRef(Object object, MongoPersistentProperty referingProperty); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/DBRef.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/DBRef.java index 07b97aae2..a5b0267ba 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/DBRef.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/DBRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 by the original author(s). + * Copyright 2011-2012 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.mongodb.core.mapping; +import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -24,19 +24,21 @@ import java.lang.annotation.Target; import org.springframework.data.annotation.Reference; /** - * An annotation that indicates the annotated field is to be stored using a com.mongodb.DBRef + * An annotation that indicates the annotated field is to be stored using a {@link com.mongodb.DBRef}. * - * @author Jon Brisbin + * @author Jon Brisbin + * @authot Oliver Gierke */ +@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD }) @Reference public @interface DBRef { - String collection() default ""; - - String id() default ""; - + /** + * The database the referred entity resides in. + * + * @return + */ String db() default ""; - } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java index 0a83b8100..8d9c6b1b0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java @@ -22,6 +22,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.convert.MongoWriter; import org.springframework.data.mongodb.core.geo.Distance; import org.springframework.data.mongodb.core.geo.Point; +import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.util.Assert; @@ -137,37 +138,33 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor { } /* - * (non-Javadoc) - * - * @see java.util.Iterator#hasNext() - */ + * (non-Javadoc) + * @see java.util.Iterator#hasNext() + */ public boolean hasNext() { return delegate.hasNext(); } /* - * (non-Javadoc) - * - * @see java.util.Iterator#next() - */ + * (non-Javadoc) + * @see java.util.Iterator#next() + */ public Object next() { - return delegate.next(); } - /* (non-Javadoc) + /* + * (non-Javadoc) * @see org.springframework.data.mongodb.repository.ConvertingParameterAccessor.PotentiallConvertingIterator#nextConverted() */ - public Object nextConverted() { - - return getConvertedValue(next()); + public Object nextConverted(MongoPersistentProperty property) { + return property.isAssociation() ? writer.toDBRef(next(), property) : getConvertedValue(next()); } /* - * (non-Javadoc) - * - * @see java.util.Iterator#remove() - */ + * (non-Javadoc) + * @see java.util.Iterator#remove() + */ public void remove() { delegate.remove(); } @@ -185,6 +182,6 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor { * * @return */ - Object nextConverted(); + Object nextConverted(MongoPersistentProperty property); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java index c91fcf4cf..52b3422fb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java @@ -98,7 +98,8 @@ class MongoQueryCreator extends AbstractQueryCreator { } PersistentPropertyPath path = context.getPersistentPropertyPath(part.getProperty()); - Criteria criteria = from(part.getType(), + MongoPersistentProperty property = path.getLeafProperty(); + Criteria criteria = from(part.getType(), property, where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), (PotentiallyConvertingIterator) iterator); @@ -116,10 +117,11 @@ class MongoQueryCreator extends AbstractQueryCreator { return create(part, iterator); } - PersistentPropertyPath path2 = context.getPersistentPropertyPath(part.getProperty()); + PersistentPropertyPath path = context.getPersistentPropertyPath(part.getProperty()); + MongoPersistentProperty property = path.getLeafProperty(); - Criteria criteria = from(part.getType(), - where(path2.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), + Criteria criteria = from(part.getType(), property, + where(path.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), (PotentiallyConvertingIterator) iterator); return criteria.andOperator(criteria); @@ -164,34 +166,36 @@ class MongoQueryCreator extends AbstractQueryCreator { } /** - * Populates the given {@link CriteriaDefinition} depending on the {@link Type} given. + * Populates the given {@link CriteriaDefinition} depending on the {@link Part} given. * - * @param type + * @param part + * @param property * @param criteria * @param parameters * @return */ - private Criteria from(Type type, Criteria criteria, PotentiallyConvertingIterator parameters) { + private Criteria from(Type type, MongoPersistentProperty property, Criteria criteria, + PotentiallyConvertingIterator parameters) { switch (type) { case GREATER_THAN: - return criteria.gt(parameters.nextConverted()); + return criteria.gt(parameters.nextConverted(property)); case GREATER_THAN_EQUAL: - return criteria.gte(parameters.nextConverted()); + return criteria.gte(parameters.nextConverted(property)); case LESS_THAN: - return criteria.lt(parameters.nextConverted()); + return criteria.lt(parameters.nextConverted(property)); case LESS_THAN_EQUAL: - return criteria.lte(parameters.nextConverted()); + return criteria.lte(parameters.nextConverted(property)); case BETWEEN: - return criteria.gt(parameters.nextConverted()).lt(parameters.nextConverted()); + return criteria.gt(parameters.nextConverted(property)).lt(parameters.nextConverted(property)); case IS_NOT_NULL: return criteria.ne(null); case IS_NULL: return criteria.is(null); case NOT_IN: - return criteria.nin(nextAsArray(parameters)); + return criteria.nin(nextAsArray(parameters, property)); case IN: - return criteria.in(nextAsArray(parameters)); + return criteria.in(nextAsArray(parameters, property)); case LIKE: String value = parameters.next().toString(); return criteria.regex(toLikeRegex(value)); @@ -225,9 +229,9 @@ class MongoQueryCreator extends AbstractQueryCreator { Object parameter = parameters.next(); return criteria.within((Shape) parameter); case SIMPLE_PROPERTY: - return criteria.is(parameters.nextConverted()); + return criteria.is(parameters.nextConverted(property)); case NEGATING_SIMPLE_PROPERTY: - return criteria.not().is(parameters.nextConverted()); + return criteria.not().is(parameters.nextConverted(property)); } throw new IllegalArgumentException("Unsupported keyword!"); @@ -253,8 +257,8 @@ class MongoQueryCreator extends AbstractQueryCreator { parameter.getClass())); } - private Object[] nextAsArray(PotentiallyConvertingIterator iterator) { - Object next = iterator.nextConverted(); + private Object[] nextAsArray(PotentiallyConvertingIterator iterator, MongoPersistentProperty property) { + Object next = iterator.nextConverted(property); if (next instanceof Collection) { return ((Collection) next).toArray(); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java index ea183dbe5..98f758f37 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoOperationsUnitTests.java @@ -37,6 +37,7 @@ import org.springframework.data.mongodb.core.query.NearQuery; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; +import com.mongodb.DBRef; /** * Abstract base class for unit tests to specify behaviour we expect from {@link MongoOperations}. Subclasses return @@ -80,6 +81,10 @@ public abstract class MongoOperationsUnitTests { public Object convertToMongoType(Object obj) { return null; } + + public DBRef toDBRef(Object object, MongoPersistentProperty referingProperty) { + return null; + } }; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index 5cbdd1ff3..a76f3a5f6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -45,17 +45,20 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; +import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.mapping.model.MappingInstantiationException; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.PersonPojoStringId; import org.springframework.test.util.ReflectionTestUtils; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; +import com.mongodb.DBRef; /** * Unit tests for {@link MappingMongoConverter}. @@ -1031,6 +1034,37 @@ public class MappingMongoConverterUnitTests { assertSyntheticFieldValueOf(outer.inner, outer); } + /** + * @see DATAMONGO-347 + */ + @Test + public void createsSimpleDBRefCorrectly() { + + Person person = new Person(); + person.id = "foo"; + + DBRef dbRef = converter.toDBRef(person, null); + assertThat(dbRef.getId(), is((Object) "foo")); + assertThat(dbRef.getRef(), is("person")); + } + + /** + * @see DATAMONGO-347 + */ + @Test + public void createsDBRefWithClientSpecCorrectly() { + + PropertyPath path = PropertyPath.from("person", PersonClient.class); + MongoPersistentProperty property = mappingContext.getPersistentPropertyPath(path).getLeafProperty(); + + Person person = new Person(); + person.id = "foo"; + + DBRef dbRef = converter.toDBRef(person, property); + assertThat(dbRef.getId(), is((Object) "foo")); + assertThat(dbRef.getRef(), is("person")); + } + private static void assertSyntheticFieldValueOf(Object target, Object expected) { for (int i = 0; i < 10; i++) { @@ -1081,6 +1115,10 @@ public class MappingMongoConverterUnitTests { } static class Person implements Contact { + + @Id + String id; + LocalDate birthDate; @Field("foo") @@ -1185,6 +1223,12 @@ public class MappingMongoConverterUnitTests { Inner inner; } + static class PersonClient { + + @org.springframework.data.mongodb.core.mapping.DBRef + Person person; + } + private class LocalDateToDateConverter implements Converter { public Date convert(LocalDate source) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java index 19b32df3b..5d436cd8e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; +import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.geo.Box; import org.springframework.data.mongodb.core.geo.Circle; import org.springframework.data.mongodb.core.geo.Distance; @@ -53,6 +54,10 @@ public abstract class AbstractPersonRepositoryIntegrationTests { @Autowired protected PersonRepository repository; + + @Autowired + MongoOperations operations; + Person dave, oliver, carter, boyd, stefan, leroi, alicia; QPerson person; @@ -404,4 +409,25 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(result.get(5), is(oliver)); assertThat(result.get(6), is(stefan)); } + + /** + * @see DATAMONGO-347 + */ + @Test + public void executesQueryWithDBRefReferenceCorrectly() { + + operations.remove(new org.springframework.data.mongodb.core.query.Query(), User.class); + + User user = new User(); + user.username = "Oliver"; + + operations.save(user); + + dave.creator = user; + repository.save(dave); + + List result = repository.findByCreator(user); + assertThat(result.size(), is(1)); + assertThat(result, hasItem(dave)); + } } \ No newline at end of file diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java index 3d4934aff..2c2b8cb31 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/Person.java @@ -20,6 +20,7 @@ import java.util.Set; import org.springframework.data.mongodb.core.geo.Point; import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; import org.springframework.data.mongodb.core.index.Indexed; +import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Document; /** @@ -48,6 +49,9 @@ public class Person extends Contact { private Address address; private Set
shippingAddresses; + @DBRef + User creator; + public Person() { this(null, null); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java index 00b050d1a..aca794603 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java @@ -151,4 +151,6 @@ public interface PersonRepository extends MongoRepository, Query GeoResults findByLocationNear(Point point, Distance maxDistance); GeoPage findByLocationNear(Point point, Distance maxDistance, Pageable pageable); + + List findByCreator(User user); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/User.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/User.java new file mode 100644 index 000000000..a0ae8aa39 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/User.java @@ -0,0 +1,27 @@ +/* + * Copyright 2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.repository; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document +public class User { + + @Id + String id; + String username; +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java index e5a221610..ecfcd5028 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java @@ -30,6 +30,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; @@ -39,6 +40,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.geo.Distance; import org.springframework.data.mongodb.core.geo.Metrics; import org.springframework.data.mongodb.core.geo.Point; +import org.springframework.data.mongodb.core.mapping.DBRef; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; @@ -212,7 +214,7 @@ public class MongoQueryCreatorUnitTests { } /** - * @see DATAMONGO + * @see DATAMONGO-413 */ @Test public void createsOrQueryCorrectly() { @@ -225,6 +227,23 @@ public class MongoQueryCreatorUnitTests { is(query(new Criteria().orOperator(where("firstName").is("Dave"), where("age").is(42))).getQueryObject())); } + /** + * @see DATAMONGO-347 + */ + @Test + public void createsQueryReferencingADBRefCorrectly() { + + User user = new User(); + com.mongodb.DBRef dbref = new com.mongodb.DBRef(null, "user", "id"); + when(converter.toDBRef(eq(user), Mockito.any(MongoPersistentProperty.class))).thenReturn(dbref); + + PartTree tree = new PartTree("findByCreator", User.class); + MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, user), context); + Query query = creator.createQuery(); + + assertThat(query.getQueryObject(), is(query(where("creator").is(dbref)).getQueryObject())); + } + private void assertBindsDistanceToQuery(Point point, Distance distance, Query reference) throws Exception { when(converter.convertToMongoType("Dave")).thenReturn("Dave"); @@ -252,5 +271,8 @@ public class MongoQueryCreatorUnitTests { @Field("foo") String username; + + @DBRef + User creator; } }