From fa810af5e201e999bad5113f12460ceb0dfe0068 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 9 Jul 2014 07:04:08 +0200 Subject: [PATCH 1/2] DATAMONGO-972 - Handle references correctly when using QueryDSL. Prepare issue branch. --- pom.xml | 2 +- spring-data-mongodb-cross-store/pom.xml | 4 ++-- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb-log4j/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index a5b1a5ba1d..4512943770 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 1.6.0.BUILD-SNAPSHOT + 1.6.0.DATAMONGO-972-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml index df9b2107a0..2cac46fed0 100644 --- a/spring-data-mongodb-cross-store/pom.xml +++ b/spring-data-mongodb-cross-store/pom.xml @@ -6,7 +6,7 @@ org.springframework.data spring-data-mongodb-parent - 1.6.0.BUILD-SNAPSHOT + 1.6.0.DATAMONGO-972-SNAPSHOT ../pom.xml @@ -48,7 +48,7 @@ org.springframework.data spring-data-mongodb - 1.6.0.BUILD-SNAPSHOT + 1.6.0.DATAMONGO-972-SNAPSHOT diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index 90e912f679..28c9a96aa3 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -13,7 +13,7 @@ org.springframework.data spring-data-mongodb-parent - 1.6.0.BUILD-SNAPSHOT + 1.6.0.DATAMONGO-972-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-log4j/pom.xml b/spring-data-mongodb-log4j/pom.xml index 82ecfa46d5..ee3c13cad9 100644 --- a/spring-data-mongodb-log4j/pom.xml +++ b/spring-data-mongodb-log4j/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 1.6.0.BUILD-SNAPSHOT + 1.6.0.DATAMONGO-972-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 25453a7917..b85069715a 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-mongodb-parent - 1.6.0.BUILD-SNAPSHOT + 1.6.0.DATAMONGO-972-SNAPSHOT ../pom.xml From 6ef83e2a17d796ee1c15377331867154ae30002e Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 9 Jul 2014 09:31:24 +0200 Subject: [PATCH 2/2] DATAMONGO-972 - Handle references correctly when using QueryDSL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SpringDataMongodbSerializer now uses the overrides for isReference and asReference to create the appropriate DBRef objects when serializing. Therefore we look for the meta-annotation @Reference and inspect the given Path to determine the property and its meta information like ‘collection’. The change will only take effect when using QueryDSL 3.4.1 and above. See querydsl/querydsl#803 for details. --- .../support/SpringDataMongodbSerializer.java | 49 ++++++++++++++++++- .../data/mongodb/repository/Person.java | 4 ++ .../PersonRepositoryIntegrationTests.java | 32 +++++++++++- 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java index 0cfda50f07..05d907d16c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 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. @@ -17,6 +17,8 @@ import java.util.regex.Pattern; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.data.annotation.Reference; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.convert.QueryMapper; @@ -25,7 +27,10 @@ import org.springframework.util.Assert; import com.mongodb.DBObject; +import com.mongodb.DBRef; import com.mysema.query.mongodb.MongodbSerializer; +import com.mysema.query.types.Constant; +import com.mysema.query.types.Operation; import com.mysema.query.types.Path; import com.mysema.query.types.PathMetadata; import com.mysema.query.types.PathType; @@ -34,6 +39,7 @@ * Custom {@link MongodbSerializer} to take mapping information into account when building keys for constraints. * * @author Oliver Gierke + * @author Christoph Strobl */ class SpringDataMongodbSerializer extends MongodbSerializer { @@ -86,4 +92,45 @@ protected DBObject asDBObject(String key, Object value) { return super.asDBObject(key, value instanceof Pattern ? value : converter.convertToMongoType(value)); } + + @Override + protected boolean isReference(Path arg) { + return AnnotationUtils.getAnnotation(arg.getAnnotatedElement(), Reference.class) != null; + } + + /* + * (non-Javadoc) + * @see com.mysema.query.mongodb.MongodbSerializer#asReference(java.lang.Object) + */ + @Override + protected DBRef asReference(Object constant) { + return converter.toDBRef(constant, null); + } + + /* + * (non-Javadoc) + * @see com.mysema.query.mongodb.MongodbSerializer#asReference(com.mysema.query.types.Operation, int) + */ + @Override + protected DBRef asReference(Operation expr, int constIndex) { + + for (Object arg : expr.getArgs()) { + if (arg instanceof Path) { + return convertToDBRef(((Constant) expr.getArg(constIndex)).getConstant(), (Path) arg); + } + } + + return super.asReference(expr, constIndex); + } + + private DBRef convertToDBRef(Object source, Path path) { + + MongoPersistentProperty property = null; + if (path.getMetadata().getParent() != null) { + MongoPersistentEntity entity = mappingContext.getPersistentEntity(path.getMetadata().getParent().getType()); + property = entity != null ? entity.getPersistentProperty(path.getMetadata().getName()) : null; + } + + return converter.toDBRef(source, property); + } } 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 11dd6abf4c..3186d78396 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 @@ -267,6 +267,10 @@ public Person withAddress(Address address) { return this; } + public void setCreator(User creator) { + this.creator = creator; + } + /* * (non-Javadoc) * diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryIntegrationTests.java index 8dfde08b7f..074eda9784 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepositoryIntegrationTests.java @@ -15,6 +15,10 @@ */ package org.springframework.data.mongodb.repository; +import static org.hamcrest.core.Is.*; +import static org.junit.Assert.*; + +import org.junit.Test; import org.springframework.test.context.ContextConfiguration; /** @@ -24,4 +28,30 @@ * @author Thomas Darimont */ @ContextConfiguration -public class PersonRepositoryIntegrationTests extends AbstractPersonRepositoryIntegrationTests {} +public class PersonRepositoryIntegrationTests extends AbstractPersonRepositoryIntegrationTests { + + /** + * ATTENTION:
+ * Test requires {@literal com.mysema.querydsl:querydsl-mongodb:3.4.1} to run!
+ * Run with: {@code mvn -Dquerydsl=3.4.1 clean install}.
+ *
+ * TODO: move this one to AbstractPersonRepositoryIntegrationTests. + * + * @see DATAMONGO-972 + */ + @Test + public void shouldExecuteFindOnDbRefCorrectly() { + + operations.remove(new org.springframework.data.mongodb.core.query.Query(), User.class); + + User user = new User(); + user.setUsername("Valerie Matthews"); + + operations.save(user); + + dave.setCreator(user); + operations.save(dave); + + assertThat(repository.findOne(QPerson.person.creator.eq(user)), is(dave)); + } +}