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 a0e07a13c..b463a108b 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 @@ -305,7 +305,7 @@ public class QueryMapper { */ protected Object convertAssociation(Object source, MongoPersistentProperty property) { - if (property == null || source == null || source instanceof DBRef) { + if (property == null || source == null || source instanceof DBRef || source instanceof DBObject) { return source; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index f4eb02f37..8cad514d4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -57,6 +57,7 @@ import com.mongodb.QueryBuilder; * @author Oliver Gierke * @author Patryk Wasik * @author Thomas Darimont + * @author Christoph Strobl */ @RunWith(MockitoJUnitRunner.class) public class QueryMapperUnitTests { @@ -501,6 +502,57 @@ public class QueryMapperUnitTests { assertThat(idValuesAfter, is(idValuesBefore)); } + /** + * @see DATAMONGO-821 + */ + @Test + public void queryMapperShouldNotTryToMapDBRefListPropertyIfNestedInsideDBObjectWithinDBObject() { + + DBObject queryObject = query( + where("referenceList").is(new BasicDBObject("$nested", new BasicDBObject("$keys", 0L)))).getQueryObject(); + + DBObject mappedObject = mapper.getMappedObject(queryObject, context.getPersistentEntity(WithDBRefList.class)); + DBObject referenceObject = getAsDBObject(mappedObject, "referenceList"); + DBObject nestedObject = getAsDBObject(referenceObject, "$nested"); + + assertThat(nestedObject, is((DBObject) new BasicDBObject("$keys", 0L))); + } + + /** + * @see DATAMONGO-821 + */ + @Test + public void queryMapperShouldNotTryToMapDBRefPropertyIfNestedInsideDBObjectWithinDBObject() { + + DBObject queryObject = query(where("reference").is(new BasicDBObject("$nested", new BasicDBObject("$keys", 0L)))) + .getQueryObject(); + + DBObject mappedObject = mapper.getMappedObject(queryObject, context.getPersistentEntity(WithDBRef.class)); + DBObject referenceObject = getAsDBObject(mappedObject, "reference"); + DBObject nestedObject = getAsDBObject(referenceObject, "$nested"); + + assertThat(nestedObject, is((DBObject) new BasicDBObject("$keys", 0L))); + } + + /** + * @see DATAMONGO-821 + */ + @Test + public void queryMapperShouldMapDBRefPropertyIfNestedInDBObject() { + + Reference sample = new Reference(); + sample.id = 321L; + DBObject queryObject = query(where("reference").is(new BasicDBObject("$in", Arrays.asList(sample)))) + .getQueryObject(); + + DBObject mappedObject = mapper.getMappedObject(queryObject, context.getPersistentEntity(WithDBRef.class)); + + DBObject referenceObject = getAsDBObject(mappedObject, "reference"); + BasicDBList inObject = getAsDBList(referenceObject, "$in"); + + assertThat(inObject.get(0), is(instanceOf(com.mongodb.DBRef.class))); + } + class IdWrapper { Object id; } @@ -541,6 +593,12 @@ public class QueryMapperUnitTests { @DBRef Reference reference; } + class WithDBRefList { + + String someString; + @DBRef List referenceList; + } + class Reference { Long id; 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 e1820da66..2238d9ca4 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 @@ -51,6 +51,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * * @author Oliver Gierke * @author Thomas Darimont + * @author Christoph Strobl */ @RunWith(SpringJUnit4ClassRunner.class) public abstract class AbstractPersonRepositoryIntegrationTests { @@ -762,4 +763,25 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(result, is(arrayWithSize(1))); assertThat(result, is(arrayContaining(leroi))); } + + + /** + * @see DATAMONGO-821 + */ + @Test + public void findUsingAnnotatedQueryOnDBRef() { + + operations.remove(new org.springframework.data.mongodb.core.query.Query(), User.class); + + User user = new User(); + user.username = "Terria"; + operations.save(user); + + alicia.creator = user; + repository.save(alicia); + + Page result = repository.findByHavingCreator(new PageRequest(0, 100)); + assertThat(result.getNumberOfElements(), is(1)); + assertThat(result.getContent().get(0), is(alicia)); + } } 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 e4d1f0796..5ced733d0 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 @@ -38,6 +38,7 @@ import org.springframework.data.querydsl.QueryDslPredicateExecutor; * * @author Oliver Gierke * @author Thomas Darimont + * @author Christoph Strobl */ public interface PersonRepository extends MongoRepository, QueryDslPredicateExecutor { @@ -256,4 +257,10 @@ public interface PersonRepository extends MongoRepository, Query * @see DATAMONGO-870 */ Slice findByAgeGreaterThan(int age, Pageable pageable); + + /** + * @see DATAMONGO-821 + */ + @Query("{ creator : { $exists : true } }") + Page findByHavingCreator(Pageable page); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java index 51fafd902..0fa679064 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 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. @@ -45,6 +45,7 @@ import com.mongodb.DBObject; * Unit tests for {@link StringBasedMongoQuery}. * * @author Oliver Gierke + * @author Christoph Strobl */ @RunWith(MockitoJUnitRunner.class) public class StringBasedMongoQueryUnitTests { @@ -126,6 +127,19 @@ public class StringBasedMongoQueryUnitTests { assertThat(query.getQueryObject().get("address"), is(nullValue())); } + /** + * @see DATAMONGO-821 + */ + @Test + public void bindsDbrefCorrectly() throws Exception { + + StringBasedMongoQuery mongoQuery = createQueryForMethod("findByHavingSizeFansNotZero"); + ConvertingParameterAccessor accessor = StubParameterAccessor.getAccessor(converter, new Object[] {}); + + org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accessor); + assertThat(query.getQueryObject(), is(new BasicQuery("{ fans : { $not : { $size : 0 } } }").getQueryObject())); + } + private StringBasedMongoQuery createQueryForMethod(String name, Class... parameters) throws Exception { Method method = SampleRepository.class.getMethod(name, parameters); @@ -143,5 +157,9 @@ public class StringBasedMongoQueryUnitTests { @Query("{ 'lastname' : ?0, 'address' : ?1 }") Person findByLastnameAndAddress(String lastname, Address address); + + @Query("{ fans : { $not : { $size : 0 } } }") + Person findByHavingSizeFansNotZero(); + } }