From 163762e99e0e5e2678a1f61ea7a1fc2bdc0228a4 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 28 Oct 2014 12:54:49 +0100 Subject: [PATCH] DATAMONGO-1078 - @Query annotated repository method fails for complex Id when used with Collection type. Remove object type hint defaulting. --- .../data/mongodb/core/MongoTemplate.java | 2 +- .../core/convert/MappingMongoConverter.java | 2 +- .../ComplexIdRepositoryIntegrationTests.java | 137 ++++++++++++++++++ .../data/mongodb/repository/MyId.java | 66 +++++++++ .../mongodb/repository/UserWithComplexId.java | 68 +++++++++ .../UserWithComplexIdRepository.java | 33 +++++ 6 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexIdRepository.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index 08971acf3..6eeb75617 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -1622,7 +1622,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { if (LOGGER.isDebugEnabled()) { LOGGER.debug(String.format("find using query: %s fields: %s for class: %s in collection: %s", - serializeToJsonSafely(query), mappedFields, entityClass, collectionName)); + serializeToJsonSafely(mappedQuery), mappedFields, entityClass, collectionName)); } return executeFindMultiInternal(new FindCallback(mappedQuery, mappedFields), preparer, objectCallback, 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 cb3e1c1a2..afe46fbe5 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 @@ -944,7 +944,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return getPotentiallyConvertedSimpleWrite(obj); } - TypeInformation typeHint = typeInformation == null ? ClassTypeInformation.OBJECT : typeInformation; + TypeInformation typeHint = typeInformation; if (obj instanceof BasicDBList) { return maybeConvertList((BasicDBList) obj, typeHint); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java new file mode 100644 index 000000000..2a55f0f84 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/ComplexIdRepositoryIntegrationTests.java @@ -0,0 +1,137 @@ +/* + * Copyright 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. + * 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 static org.hamcrest.collection.IsCollectionWithSize.*; +import static org.hamcrest.collection.IsIterableContainingInOrder.*; +import static org.hamcrest.core.IsEqual.*; +import static org.junit.Assert.*; + +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.config.AbstractMongoConfiguration; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.mongodb.Mongo; +import com.mongodb.MongoClient; + +/** + * @author Christoph Strobl + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class ComplexIdRepositoryIntegrationTests { + + @Configuration + @EnableMongoRepositories + static class Config extends AbstractMongoConfiguration { + + @Override + protected String getDatabaseName() { + return "complexIdTest"; + } + + @Override + public Mongo mongo() throws Exception { + return new MongoClient(); + } + + } + + @Autowired UserWithComplexIdRepository repo; + + @Autowired MongoTemplate template; + + private MyId id; + private UserWithComplexId userWithId; + + @Before + public void setUp() { + repo.deleteAll(); + + id = new MyId(); + id.val1 = "v1"; + id.val2 = "v2"; + + userWithId = new UserWithComplexId(); + userWithId.firstname = "foo"; + userWithId.id = id; + } + + /** + * @see DATAMONGO-1078 + */ + @Test + public void annotatedFindQueryShouldWorkWhenUsingComplexId() { + + repo.save(userWithId); + + UserWithComplexId loaded = repo.getUserByComplexId(id); + + assertThat(loaded, equalTo(userWithId)); + } + + /** + * @see DATAMONGO-1078 + */ + @Test + public void annotatedFindQueryShouldWorkWhenUsingComplexIdWithinCollection() { + + repo.save(userWithId); + + List loaded = repo.findByUserIds(Collections.singleton(id)); + + assertThat(loaded, hasSize(1)); + assertThat(loaded, contains(userWithId)); + } + + /** + * @see DATAMONGO-1078 + */ + @Test + public void findOneShouldWorkWhenUsingComplexId() { + + repo.save(userWithId); + + UserWithComplexId loaded = repo.findOne(id); + + assertThat(loaded, equalTo(userWithId)); + } + + /** + * @see DATAMONGO-1078 + */ + @Test + public void findAllShouldWorkWhenUsingComplexId() { + + repo.save(userWithId); + + List loaded = (List) repo.findAll(Collections.singleton(id)); + + assertThat(loaded, hasSize(1)); + assertThat(loaded, contains(userWithId)); + } + +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java new file mode 100644 index 000000000..b5f6dadee --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/MyId.java @@ -0,0 +1,66 @@ +/* + * Copyright 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. + * 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 java.io.Serializable; + +/** + * @author Christoph Strobl + */ +public class MyId implements Serializable { + + String val1; + String val2; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((val1 == null) ? 0 : val1.hashCode()); + result = prime * result + ((val2 == null) ? 0 : val2.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof MyId)) { + return false; + } + MyId other = (MyId) obj; + if (val1 == null) { + if (other.val1 != null) { + return false; + } + } else if (!val1.equals(other.val1)) { + return false; + } + if (val2 == null) { + if (other.val2 != null) { + return false; + } + } else if (!val2.equals(other.val2)) { + return false; + } + return true; + } + +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java new file mode 100644 index 000000000..b9235a78c --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexId.java @@ -0,0 +1,68 @@ +/* + * Copyright 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. + * 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; + +/** + * @author Christoph Strobl + */ +@Document +public class UserWithComplexId { + + @Id MyId id; + String firstname; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((firstname == null) ? 0 : firstname.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof UserWithComplexId)) { + return false; + } + UserWithComplexId other = (UserWithComplexId) obj; + if (firstname == null) { + if (other.firstname != null) { + return false; + } + } else if (!firstname.equals(other.firstname)) { + return false; + } + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + return true; + } + +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexIdRepository.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexIdRepository.java new file mode 100644 index 000000000..880edd7a1 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/UserWithComplexIdRepository.java @@ -0,0 +1,33 @@ +/* + * Copyright 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. + * 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 java.util.Collection; +import java.util.List; + +import org.springframework.data.repository.CrudRepository; + +/** + * @author Christoph Strobl + */ +public interface UserWithComplexIdRepository extends CrudRepository { + + @Query("{'_id': {$in: ?0}}") + List findByUserIds(Collection ids); + + @Query("{'_id': ?0}") + UserWithComplexId getUserByComplexId(MyId id); +}