From 48b4a88a6a3474402cf01c8ffb938dc04687816e Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 27 Mar 2013 11:20:08 +0100 Subject: [PATCH] DATAMONGO-629 - Fixed QueryMapper not to massage queries without type information. So far the QueryMapper applied the id massaging (especially interpreting the default id keys) even if there was no persistence metadata available to do so. This caused e.g. queries handed into MongoTemplate.count(Query, String) to get keys of "id" massaged into "_id" which shouldn't be the case as we cannot assume anything about the documents and the keys contained in them. So we now only apply the defaults if there is at least persistence metadata present. This means that for methods on MongoOperations that don't take type information of any kind the queries have to be defined in terms of the document, not the object model as we cannot refer to it. --- .../data/mongodb/core/convert/QueryMapper.java | 8 ++++++-- .../core/mapping/MongoMappingContext.java | 3 ++- .../data/mongodb/core/MongoTemplateTests.java | 16 ++++++++++++++++ .../core/convert/QueryMapperUnitTests.java | 18 +++++++++++++++++- 4 files changed, 41 insertions(+), 4 deletions(-) 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 1df9f9be7..d0b8e6505 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 @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-2013 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. @@ -214,7 +214,11 @@ public class QueryMapper { */ private String determineKey(String key, MongoPersistentEntity entity) { - if (entity == null && DEFAULT_ID_NAMES.contains(key)) { + if (entity == null) { + return key; + } + + if (!entity.hasIdProperty() && DEFAULT_ID_NAMES.contains(key)) { return "_id"; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java index de5cc1a85..a4b9b1a7a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.mapping; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; +import java.util.HashMap; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -51,7 +52,7 @@ public class MongoMappingContext extends AbstractMappingContext type) { - return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType()); + return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType()) && !type.getType().equals(HashMap.class); } /* diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index bc650e603..0bebcd891 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -1517,6 +1517,22 @@ public class MongoTemplateTests { template.save(person); } + /** + * @see DATAMONGO-629 + */ + @Test + public void countAndFindWithoutTypeInformation() { + + Person person = new Person(); + template.save(person); + + Query query = query(where("_id").is(person.getId())); + String collectionName = template.getCollectionName(Person.class); + + assertThat(template.find(query, HashMap.class, collectionName), hasSize(1)); + assertThat(template.count(query, collectionName), is(1L)); + } + static class MyId { String first; 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 7c0f44525..742869326 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 @@ -1,5 +1,5 @@ /* - * Copyright 2011-2012 the original author or authors. + * Copyright 2011-2013 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. @@ -347,6 +347,22 @@ public class QueryMapperUnitTests { assertThat(object.get("reference"), is(nullValue())); } + /** + * @see DATAMONGO-629 + */ + @Test + public void doesNotMapIdIfNoEntityMetadataAvailable() { + + String id = new ObjectId().toString(); + Query query = query(where("id").is(id)); + + DBObject object = mapper.getMappedObject(query.getQueryObject(), null); + + assertThat(object.containsField("id"), is(true)); + assertThat(object.get("id"), is((Object) id)); + assertThat(object.containsField("_id"), is(false)); + } + class IdWrapper { Object id; }