diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java index f6c0f8384..741c3aeae 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java @@ -49,18 +49,18 @@ public abstract class DocumentTestUtils { /** * Expects the field with the given key to be not {@literal null} and a {@link BasicDBList}. * - * @param source the {@link Document} to lookup the {@link BasicDBList} in - * @param key the key of the field to find the {@link BasicDBList} in + * @param source the {@link Document} to lookup the {@link List} in + * @param key the key of the field to find the {@link List} in * @return */ - public static List getAsDBList(Document source, String key) { + public static List getAsDBList(Document source, String key) { return getTypedValue(source, key, List.class); } /** * Expects the list element with the given index to be a non-{@literal null} {@link Document} and returns it. * - * @param source the {@link BasicDBList} to look up the {@link Document} element in + * @param source the {@link List} to look up the {@link Document} element in * @param index the index of the element expected to contain a {@link Document} * @return */ 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 1b567948d..7bcd343a8 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 @@ -3482,7 +3482,7 @@ public class MongoTemplateTests { Document document = new Document(); - template.insertAll(Arrays.asList(document)); + template.insertAll(Collections.singletonList(document)); assertThat(document.id, is(notNullValue())); } @@ -3492,9 +3492,9 @@ public class MongoTemplateTests { * @see DATAMONGO-1509 */ @Test - public void findsByGnericNestedListElements() { + public void findsByGenericNestedListElements() { - List modelList = Arrays.asList(new ModelA("value")); + List modelList = Collections.singletonList(new ModelA("value")); DocumentWithCollection dwc = new DocumentWithCollection(modelList); template.insert(dwc); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java index a566bd10a..58c7ea4e3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java @@ -102,7 +102,7 @@ public class UpdateMapperUnitTests { Document push = getAsDocument(mappedObject, "$push"); Document list = getAsDocument(push, "aliased"); - assertThat(list.get("_class"), is(ConcreteChildClass.class.getName())); + assertTypeHint(list, ConcreteChildClass.class); } /** @@ -119,7 +119,7 @@ public class UpdateMapperUnitTests { Document set = getAsDocument(mappedObject, "$set"); Document modelDocument = (Document) set.get("model"); - assertThat(modelDocument.get("_class"), not(nullValue())); + assertTypeHint(modelDocument, ModelImpl.class); } /** @@ -168,7 +168,7 @@ public class UpdateMapperUnitTests { Document set = getAsDocument(mappedObject, "$set"); Document modelDocument = getAsDocument(set, "aliased.$"); - assertThat(modelDocument.get("_class"), is(ConcreteChildClass.class.getName())); + assertTypeHint(modelDocument, ConcreteChildClass.class); } /** @@ -205,8 +205,8 @@ public class UpdateMapperUnitTests { Document someObject = getAsDocument(document, "aliased.$.someObject"); assertThat(someObject, is(notNullValue())); - assertThat(someObject.get("_class"), is(ConcreteChildClass.class.getName())); assertThat(someObject.get("value"), is("bubu")); + assertTypeHint(someObject, ConcreteChildClass.class); } /** @@ -276,9 +276,9 @@ public class UpdateMapperUnitTests { Document push = getAsDocument(mappedObject, "$push"); Document model = getAsDocument(push, "models"); - List each = getAsDBList(model, "$each"); + List each = getAsDBList(model, "$each"); - assertThat(((Document) each.get(0)).get("_class").toString(), equalTo(ListModel.class.getName())); + assertTypeHint(each.get(0), ListModel.class); } /** @@ -566,8 +566,7 @@ public class UpdateMapperUnitTests { List each = getAsDBList(values, "$each"); for (Object updateValue : each) { - assertThat(((Document) updateValue).get("_class").toString(), - equalTo("org.springframework.data.mongodb.core.convert.UpdateMapperUnitTests$ModelImpl")); + assertTypeHint((Document) updateValue, ModelImpl.class); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java index bc258a5d8..5f64df458 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java @@ -19,6 +19,7 @@ import static org.hamcrest.collection.IsCollectionWithSize.*; import static org.hamcrest.core.Is.*; import static org.hamcrest.core.IsEqual.*; import static org.junit.Assert.*; +import static org.springframework.data.mongodb.core.DocumentTestUtils.assertTypeHint; import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; @@ -421,9 +422,9 @@ public class ApplicationContextEventTests { assertEquals(p.getId(), p2.getId()); assertEquals(p.getText(), p2.getText()); - assertEquals("org.springframework.data.mongodb.core.mapping.PersonPojoStringId", document.get("_class")); assertEquals("1", document.get("_id")); assertEquals("Text", document.get("text")); + assertTypeHint(document, PersonPojoStringId.class); } @Data diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc index 8066c6a08..98e753396 100644 --- a/src/main/asciidoc/new-features.adoc +++ b/src/main/asciidoc/new-features.adoc @@ -1,6 +1,12 @@ [[new-features]] = New & Noteworthy +[[new-features.2-0-0]] +== What's new in Spring Data MongoDB 2.0 +* Upgrade to Java 8. +* Usage of the `Document` API instead of `DBObject`. +* <>. + [[new-features.1-10-0]] == What's new in Spring Data MongoDB 1.10 * Support for `$min`, `$max` and `$slice` operators via `Update`. diff --git a/src/main/asciidoc/reference/mongo-repositories.adoc b/src/main/asciidoc/reference/mongo-repositories.adoc index eb053f892..d56783007 100644 --- a/src/main/asciidoc/reference/mongo-repositories.adoc +++ b/src/main/asciidoc/reference/mongo-repositories.adoc @@ -273,6 +273,8 @@ NOTE: Note that for version 1.0 we currently don't support referring to paramete | `{"location" : {"$exists" : exists }}` |=== +NOTE: If the property criterion compares a document, the order of the fields and exact equality in the document matters. + [[mongodb.repositories.queries.delete]] === Repository delete queries diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc index ada5948fc..5f8387e37 100644 --- a/src/main/asciidoc/reference/mongodb.adoc +++ b/src/main/asciidoc/reference/mongodb.adoc @@ -666,7 +666,8 @@ When querying and updating `MongoTemplate` will use the converter to handle conv As MongoDB collections can contain documents that represent instances of a variety of types. A great example here is if you store a hierarchy of classes or simply have a class with a property of type `Object`. In the latter case the values held inside that property have to be read in correctly when retrieving the object. Thus we need a mechanism to store type information alongside the actual document. -To achieve that the `MappingMongoConverter` uses a `MongoTypeMapper` abstraction with `DefaultMongoTypeMapper` as it's main implementation. Its default behavior is storing the fully qualified classname under `_class` inside the document for the top-level document as well as for every value if it's a complex type and a subtype of the property type declared. +To achieve that the `MappingMongoConverter` uses a `MongoTypeMapper` abstraction with `DefaultMongoTypeMapper` as it's main implementation. Its default behavior is storing the fully qualified classname under `_class` inside the document. Type hints are written for top-level documents as well as for every value if it's a complex type and a subtype of the property type declared. + .Type mapping ==== @@ -685,13 +686,14 @@ sample.value = new Person(); mongoTemplate.save(sample); -{ "_class" : "com.acme.Sample", - "value" : { "_class" : "com.acme.Person" } +{ + "value" : { "_class" : "com.acme.Person" }, + "_class" : "com.acme.Sample" } ---- ==== -As you can see we store the type information for the actual root class persistent as well as for the nested type as it is complex and a subtype of `Contact`. So if you're now using `mongoTemplate.findAll(Object.class, "sample")` we are able to find out that the document stored shall be a `Sample` instance. We are also able to find out that the value property shall be a `Person` actually. +As you can see we store the type information as last field for the actual root class as well as for the nested type as it is complex and a subtype of `Contact`. So if you're now using `mongoTemplate.findAll(Object.class, "sample")` we are able to find out that the document stored shall be a `Sample` instance. We are also able to find out that the value property shall be a `Person` actually. ==== Customizing type mapping @@ -1053,7 +1055,7 @@ As you can see most methods return the `Criteria` object to provide a fluent sty * `Criteria` *gte* `(Object o)` Creates a criterion using the `$gte` operator * `Criteria` *in* `(Object... o)` Creates a criterion using the `$in` operator for a varargs argument. * `Criteria` *in* `(Collection collection)` Creates a criterion using the `$in` operator using a collection -* `Criteria` *is* `(Object o)` Creates a criterion using the `$is` operator +* `Criteria` *is* `(Object o)` Creates a criterion using field matching (`{ key:value }`). If the specified value is a document, the order of the fields and exact equality in the document matters. * `Criteria` *lt* `(Object o)` Creates a criterion using the `$lt` operator * `Criteria` *lte* `(Object o)` Creates a criterion using the `$lte` operator * `Criteria` *mod* `(Number value, Number remainder)` Creates a criterion using the `$mod` operator