From e2f39667631070f14c7b6a2f7be92f7cd37a2d1a Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 9 Jul 2014 09:31:24 +0200 Subject: [PATCH] DATAMONGO-972 - Querydsl integration now handles references correctly. SpringDataMongodbSerializer now overrides the necessary methods to create the appropriate DBRef objects when serializing data via Querydsl. We currently disable the test case as it the fix taking effect requires Querydsl 3.4.1 which unfortunately breaks Java 6 compatibility. We include the fix nonetheless to allow users on Java 7 to potentially use the latest Querydsl. Original pull request: #203. Related tickets: querydsl/querydsl#803. --- .../support/SpringDataMongodbSerializer.java | 61 ++++++++++++++++++- ...tractPersonRepositoryIntegrationTests.java | 23 +++++++ .../data/mongodb/repository/Person.java | 4 ++ 3 files changed, 86 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 0cfda50f0..e98ce9cf2 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. @@ -25,7 +25,10 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; 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 +37,7 @@ import com.mysema.query.types.PathType; * Custom {@link MongodbSerializer} to take mapping information into account when building keys for constraints. * * @author Oliver Gierke + * @author Christoph Strobl */ class SpringDataMongodbSerializer extends MongodbSerializer { @@ -44,7 +48,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { /** * Creates a new {@link SpringDataMongodbSerializer} for the given {@link MappingContext}. * - * @param mappingContext + * @param mappingContext must not be {@literal null}. */ public SpringDataMongodbSerializer(MongoConverter converter) { @@ -86,4 +90,57 @@ class SpringDataMongodbSerializer extends MongodbSerializer { return super.asDBObject(key, value instanceof Pattern ? value : converter.convertToMongoType(value)); } + + /* + * (non-Javadoc) + * @see com.mysema.query.mongodb.MongodbSerializer#isReference(com.mysema.query.types.Path) + */ + @Override + protected boolean isReference(Path path) { + + MongoPersistentProperty property = getPropertyFor(path); + return property == null ? false : property.isAssociation(); + } + + /* + * (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) { + + MongoPersistentProperty property = getPropertyFor((Path) arg); + Object constant = ((Constant) expr.getArg(constIndex)).getConstant(); + + return converter.toDBRef(constant, property); + } + } + + return super.asReference(expr, constIndex); + } + + private MongoPersistentProperty getPropertyFor(Path path) { + + Path parent = path.getMetadata().getParent(); + + if (parent == null) { + return null; + } + + MongoPersistentEntity entity = mappingContext.getPersistentEntity(parent.getType()); + return entity != null ? entity.getPersistentProperty(path.getMetadata().getName()) : null; + } } 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 757822de8..de34b08c4 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 @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.List; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -918,4 +919,26 @@ public abstract class AbstractPersonRepositoryIntegrationTests { assertThat(result.getTotalPages(), is(2)); assertThat(result.getTotalElements(), is(3L)); } + + /** + * Ignored for now as this requires Querydsl 3.4.1 to succeed. + * + * @see DATAMONGO-972 + */ + @Test + @Ignore + 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)); + } } 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 11dd6abf4..3186d7839 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 class Person extends Contact { return this; } + public void setCreator(User creator) { + this.creator = creator; + } + /* * (non-Javadoc) *