@ -68,7 +65,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -68,7 +65,7 @@ public class ConditionalOperator implements AggregationExpression {
@ -96,7 +93,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -96,7 +93,7 @@ public class ConditionalOperator implements AggregationExpression {
@ -112,7 +109,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -112,7 +109,7 @@ public class ConditionalOperator implements AggregationExpression {
@ -125,7 +122,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -125,7 +122,7 @@ public class ConditionalOperator implements AggregationExpression {
@ -144,7 +141,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -144,7 +141,7 @@ public class ConditionalOperator implements AggregationExpression {
}
thrownewInvalidDataAccessApiUsageException(
String.format("Invalid value in condition. Supported: DBObject, Field references, Criteria, got: %s",value));
String.format("Invalid value in condition. Supported: Document, Field references, Criteria, got: %s",value));
@ -173,7 +170,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -173,7 +170,7 @@ public class ConditionalOperator implements AggregationExpression {
}
}
clauses.add(newBasicDBObject(key,args));
clauses.add(newDocument(key,args));
}elseif(predicateinstanceofDocument){
@ -188,7 +185,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -188,7 +185,7 @@ public class ConditionalOperator implements AggregationExpression {
List<Object>args=newArrayList<Object>();
args.add("$"+key);
args.add(nested.get(s));
clauses.add(newBasicDBObject(s,args));
clauses.add(newDocument(s,args));
}
}elseif(!isKeyword(key)){
@ -196,7 +193,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -196,7 +193,7 @@ public class ConditionalOperator implements AggregationExpression {
List<Object>args=newArrayList<Object>();
args.add("$"+key);
args.add(predicate);
clauses.add(newBasicDBObject("$eq",args));
clauses.add(newDocument("$eq",args));
}
returnclauses;
@ -271,7 +268,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -271,7 +268,7 @@ public class ConditionalOperator implements AggregationExpression {
@ -285,7 +282,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -285,7 +282,7 @@ public class ConditionalOperator implements AggregationExpression {
@ -317,7 +314,7 @@ public class ConditionalOperator implements AggregationExpression {
@@ -317,7 +314,7 @@ public class ConditionalOperator implements AggregationExpression {
@ -56,7 +52,7 @@ public class IfNullOperator implements AggregationExpression {
@@ -56,7 +52,7 @@ public class IfNullOperator implements AggregationExpression {
@ -73,7 +69,7 @@ public class IfNullOperator implements AggregationExpression {
@@ -73,7 +69,7 @@ public class IfNullOperator implements AggregationExpression {
@ -120,7 +116,7 @@ public class IfNullOperator implements AggregationExpression {
@@ -120,7 +116,7 @@ public class IfNullOperator implements AggregationExpression {
@ -438,7 +438,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
@@ -438,7 +438,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
@ -169,7 +170,6 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<Bson> implements M
@@ -169,7 +170,6 @@ public class DefaultMongoTypeMapper extends DefaultTypeMapper<Bson> implements M
@ -122,7 +122,7 @@ In addition to these types, Spring Data MongoDB provides a set of built-in conve
@@ -122,7 +122,7 @@ In addition to these types, Spring Data MongoDB provides a set of built-in conve
| native
| `{"value" : null}`
| `DBObject`
| `Document`
| native
| `{"value" : { … }}`
@ -392,7 +392,7 @@ The MappingMongoConverter can use metadata to drive the mapping of objects to do
@@ -392,7 +392,7 @@ The MappingMongoConverter can use metadata to drive the mapping of objects to do
* `@TextIndexed` - applied at the field level to mark the field to be included in the text index.
* `@Language` - applied at the field level to set the language override property for text index.
* `@Transient` - by default all private fields are mapped to the document, this annotation excludes the field where it is applied from being stored in the database
* `@PersistenceConstructor` - marks a given constructor - even a package protected one - to use when instantiating the object from the database. Constructor arguments are mapped by name to the key values in the retrieved DBObject.
* `@PersistenceConstructor` - marks a given constructor - even a package protected one - to use when instantiating the object from the database. Constructor arguments are mapped by name to the key values in the retrieved Document.
* `@Value` - this annotation is part of the Spring Framework . Within the mapping framework it can be applied to constructor arguments. This lets you use a Spring Expression Language statement to transform a key's value retrieved in the database before it is used to construct a domain object. In order to reference a property of a given document one has to use expressions like: `@Value("#root.myProperty")` where `root` refers to the root of the given document.
* `@Field` - applied at the field level and described the name of the field as it will be represented in the MongoDB BSON document thus allowing the name to be different than the fieldname of the class.
* `@Version` - applied at field level is used for optimistic locking and checked for modification on save operations. The initial value is `zero` which is bumped automatically on every update.
@ -484,7 +484,7 @@ class OrderItem {
@@ -484,7 +484,7 @@ class OrderItem {
@ -599,7 +599,7 @@ Simply declaring these beans in your Spring ApplicationContext will cause them t
@@ -599,7 +599,7 @@ Simply declaring these beans in your Spring ApplicationContext will cause them t
[[mapping-explicit-converters]]
=== Overriding Mapping with explicit Converters
When storing and querying your objects it is convenient to have a `MongoConverter` instance handle the mapping of all Java types to DBObjects. However, sometimes you may want the `MongoConverter` s do most of the work but allow you to selectively handle the conversion for a particular type or to optimize performance.
When storing and querying your objects it is convenient to have a `MongoConverter` instance handle the mapping of all Java types to Documents. However, sometimes you may want the `MongoConverter` s do most of the work but allow you to selectively handle the conversion for a particular type or to optimize performance.
To selectively handle the conversion yourself, register one or more one or more `org.springframework.core.convert.converter.Converter` instances with the MongoConverter.
@ -607,14 +607,14 @@ NOTE: Spring 3.0 introduced a core.convert package that provides a general type
@@ -607,14 +607,14 @@ NOTE: Spring 3.0 introduced a core.convert package that provides a general type
The method `customConversions` in `AbstractMongoConfiguration` can be used to configure Converters. The examples <<mapping-configuration,here>> at the beginning of this chapter show how to perform the configuration using Java and XML.
Below is an example of a Spring Converter implementation that converts from a DBObject to a Person POJO.
Below is an example of a Spring Converter implementation that converts from a Document to a Person POJO.
[source,java]
----
@ReadingConverter
public class PersonReadConverter implements Converter<DBObject, Person> {
public class PersonReadConverter implements Converter<Document, Person> {
public Person convert(DBObject source) {
public Person convert(Document source) {
Person p = new Person((ObjectId) source.get("_id"), (String) source.get("name"));
p.setAge((Integer) source.get("age"));
return p;
@ -622,19 +622,19 @@ Below is an example of a Spring Converter implementation that converts from a DB
@@ -622,19 +622,19 @@ Below is an example of a Spring Converter implementation that converts from a DB
}
----
Here is an example that converts from a Person to a DBObject.
Here is an example that converts from a Person to a Document.
[source,java]
----
@WritingConverter
public class PersonWriteConverter implements Converter<Person, DBObject> {
public DBObject convert(Person source) {
DBObject dbo = new BasicDBObject();
dbo.put("_id", source.getId());
dbo.put("name", source.getFirstName());
dbo.put("age", source.getAge());
return dbo;
public class PersonWriteConverter implements Converter<Person, Document> {
@ -424,7 +424,7 @@ NOTE: Once configured, `MongoTemplate` is thread-safe and can be reused across m
@@ -424,7 +424,7 @@ NOTE: Once configured, `MongoTemplate` is thread-safe and can be reused across m
The mapping between MongoDB documents and domain classes is done by delegating to an implementation of the interface `MongoConverter`. Spring provides two implementations, `SimpleMappingConverter` and `MongoMappingConverter`, but you can also write your own converter. Please refer to the section on MongoConverters for more detailed information.
The `MongoTemplate` class implements the interface `MongoOperations`. In as much as possible, the methods on `MongoOperations` are named after methods available on the MongoDB driver `Collection` object to make the API familiar to existing MongoDB developers who are used to the driver API. For example, you will find methods such as "find", "findAndModify", "findOne", "insert", "remove", "save", "update" and "updateMulti". The design goal was to make it as easy as possible to transition between the use of the base MongoDB driver and `MongoOperations`. A major difference in between the two APIs is that MongoOperations can be passed domain objects instead of `DBObject` and there are fluent APIs for `Query`, `Criteria`, and `Update` operations instead of populating a `DBObject` to specify the parameters for those operations.
The `MongoTemplate` class implements the interface `MongoOperations`. In as much as possible, the methods on `MongoOperations` are named after methods available on the MongoDB driver `Collection` object to make the API familiar to existing MongoDB developers who are used to the driver API. For example, you will find methods such as "find", "findAndModify", "findOne", "insert", "remove", "save", "update" and "updateMulti". The design goal was to make it as easy as possible to transition between the use of the base MongoDB driver and `MongoOperations`. A major difference in between the two APIs is that MongoOperations can be passed domain objects instead of `Document` and there are fluent APIs for `Query`, `Criteria`, and `Update` operations instead of populating a `Document` to specify the parameters for those operations.
NOTE: The preferred way to reference the operations on `MongoTemplate` instance is via its interface `MongoOperations`.
@ -506,7 +506,7 @@ public interface WriteConcernResolver {
@@ -506,7 +506,7 @@ public interface WriteConcernResolver {
}
----
The passed in argument, MongoAction, is what you use to determine the `WriteConcern` value to be used or to use the value of the Template itself as a default. `MongoAction` contains the collection name being written to, the `java.lang.Class` of the POJO, the converted `DBObject`, as well as the operation as an enumeration (`MongoActionOperation`: REMOVE, UPDATE, INSERT, INSERT_LIST, SAVE) and a few other pieces of contextual information. For example,
The passed in argument, MongoAction, is what you use to determine the `WriteConcern` value to be used or to use the value of the Template itself as a default. `MongoAction` contains the collection name being written to, the `java.lang.Class` of the POJO, the converted `Document`, as well as the operation as an enumeration (`MongoActionOperation`: REMOVE, UPDATE, INSERT, INSERT_LIST, SAVE) and a few other pieces of contextual information. For example,
[source]
----
@ -624,7 +624,7 @@ This would produce the following log output (including debug messages from `Mong
@@ -624,7 +624,7 @@ This would produce the following log output (including debug messages from `Mong
[source]
----
DEBUG apping.MongoPersistentEntityIndexCreator: 80 - Analyzing class class org.spring.example.Person for index information.
DEBUG work.data.mongodb.core.MongoTemplate: 632 - insert DBObject containing fields: [_class, age, name] in collection: person
DEBUG work.data.mongodb.core.MongoTemplate: 632 - insert Document containing fields: [_class, age, name] in collection: person
INFO org.spring.example.MongoApp: 30 - Insert: Person [id=4ddc6e784ce5b1eba3ceaf5c, name=Joe, age=34]
DEBUG work.data.mongodb.core.MongoTemplate:1246 - findOne using query: { "_id" : { "$oid" : "4ddc6e784ce5b1eba3ceaf5c"}} in db.collection: database.person
INFO org.spring.example.MongoApp: 34 - Found: Person [id=4ddc6e784ce5b1eba3ceaf5c, name=Joe, age=34]
@ -769,7 +769,7 @@ Note that we are extending the `AbstractMongoConfiguration` class and override t
@@ -769,7 +769,7 @@ Note that we are extending the `AbstractMongoConfiguration` class and override t
[[mongo-template.save-insert]]
=== Methods for saving and inserting documents
There are several convenient methods on `MongoTemplate` for saving and inserting your objects. To have more fine-grained control over the conversion process you can register Spring converters with the `MappingMongoConverter`, for example `Converter<Person, DBObject>` and `Converter<DBObject, Person>`.
There are several convenient methods on `MongoTemplate` for saving and inserting your objects. To have more fine-grained control over the conversion process you can register Spring converters with the `MappingMongoConverter`, for example `Converter<Person, Document>` and `Converter<Document, Person>`.
NOTE: The difference between insert and save operations is that a save operation will perform an insert if the object is not already present.
=== Finding and Upserting documents in a collection
The `findAndModify(…)` method on DBCollection can update a document and return either the old or newly updated document in a single operation. `MongoTemplate` provides a findAndModify method that takes `Query` and `Update` classes and converts from `DBObject` to your POJOs. Here are the methods
The `findAndModify(…)` method on DBCollection can update a document and return either the old or newly updated document in a single operation. `MongoTemplate` provides a findAndModify method that takes `Query` and `Update` classes and converts from `Document` to your POJOs. Here are the methods
[source,java]
----
@ -1592,7 +1592,7 @@ public class XObject {
@@ -1592,7 +1592,7 @@ public class XObject {
}
----
You can also obtain the raw result as a `DbObject` by calling the method `getRawResults` on the `GroupByResults` class.
You can also obtain the raw result as a `Document` by calling the method `getRawResults` on the `GroupByResults` class.
There is an additional method overload of the group method on `MongoOperations` which lets you specify a `Criteria` object for selecting a subset of the rows. An example which uses a `Criteria` object, with some syntax sugar using static imports, as well as referencing a key-function and reduce function javascript files via a Spring Resource string is shown below.
@ -1632,7 +1632,7 @@ An `AggregationOperation` represents a MongoDB aggregation pipeline operation an
@@ -1632,7 +1632,7 @@ An `AggregationOperation` represents a MongoDB aggregation pipeline operation an
+
* `AggregationResults`
+
`AggregationResults` is the container for the result of an aggregate operation. It provides access to the raw aggregation result in the form of an `DBObject`, to the mapped objects and information which performed the aggregation.
`AggregationResults` is the container for the result of an aggregate operation. It provides access to the raw aggregation result in the form of an `Document`, to the mapped objects and information which performed the aggregation.
+
The canonical example for using the Spring Data MongoDB support for the MongoDB Aggregation Framework looks as follows:
Note that we can also refer to other fields of the document within the SpEL expression.
@ -2044,23 +2044,22 @@ NOTE: For more information on the Spring type conversion service see the referen
@@ -2044,23 +2044,22 @@ NOTE: For more information on the Spring type conversion service see the referen
[[mongo.custom-converters.writer]]
=== Saving using a registered Spring Converter
An example implementation of the `Converter` that converts from a Person object to a `com.mongodb.DBObject` is shown below
An example implementation of the `Converter` that converts from a Person object to a `org.bson.Document` is shown below
public class PersonWriteConverter implements Converter<Person, DBObject> {
public class PersonWriteConverter implements Converter<Person, Document> {
public DBObject convert(Person source) {
DBObject dbo = new BasicDBObject();
dbo.put("_id", source.getId());
dbo.put("name", source.getFirstName());
dbo.put("age", source.getAge());
return dbo;
public Document convert(Person source) {
Document document = new Document();
document.put("_id", source.getId());
document.put("name", source.getFirstName());
document.put("age", source.getAge());
return document;
}
}
----
@ -2068,13 +2067,13 @@ public class PersonWriteConverter implements Converter<Person, DBObject> {
@@ -2068,13 +2067,13 @@ public class PersonWriteConverter implements Converter<Person, DBObject> {
[[mongo.custom-converters.reader]]
=== Reading using a Spring Converter
An example implementation of a Converter that converts from a DBObject to a Person object is shown below.
An example implementation of a Converter that converts from a Document to a Person object is shown below.
[source,java]
----
public class PersonReadConverter implements Converter<DBObject, Person> {
public class PersonReadConverter implements Converter<Document, Person> {
public Person convert(DBObject source) {
public Person convert(Document source) {
Person p = new Person((ObjectId) source.get("_id"), (String) source.get("name"));
p.setAge((Integer) source.get("age"));
return p;
@ -2225,7 +2224,7 @@ You can also get at the MongoDB driver's `DB.command( )` method using the `execu
@@ -2225,7 +2224,7 @@ You can also get at the MongoDB driver's `DB.command( )` method using the `execu
[[mongo-template.commands.execution]]
=== Methods for executing commands
* `CommandResult` *executeCommand* `(DBObject command)` Execute a MongoDB command.
* `CommandResult` *executeCommand* `(Document command)` Execute a MongoDB command.
* `CommandResult` *executeCommand* `(String jsonCommand)` Execute the a MongoDB command expressed as a JSON string.
[[mongodb.mapping-usage.events]]
@ -2233,7 +2232,7 @@ You can also get at the MongoDB driver's `DB.command( )` method using the `execu
@@ -2233,7 +2232,7 @@ You can also get at the MongoDB driver's `DB.command( )` method using the `execu
Built into the MongoDB mapping framework are several `org.springframework.context.ApplicationEvent` events that your application can respond to by registering special beans in the `ApplicationContext`. By being based off Spring's ApplicationContext event infrastructure this enables other products, such as Spring Integration, to easily receive these events as they are a well known eventing mechanism in Spring based applications.
To intercept an object before it goes through the conversion process (which turns your domain object into a `com.mongodb.DBObject`), you'd register a subclass of `AbstractMongoEventListener` that overrides the `onBeforeConvert` method. When the event is dispatched, your listener will be called and passed the domain object before it goes into the converter.
To intercept an object before it goes through the conversion process (which turns your domain object into a `org.bson.Document`), you'd register a subclass of `AbstractMongoEventListener` that overrides the `onBeforeConvert` method. When the event is dispatched, your listener will be called and passed the domain object before it goes into the converter.
====
[source,java]
@ -2247,7 +2246,7 @@ public class BeforeConvertListener extends AbstractMongoEventListener<Person> {
@@ -2247,7 +2246,7 @@ public class BeforeConvertListener extends AbstractMongoEventListener<Person> {
----
====
To intercept an object before it goes into the database, you'd register a subclass of `org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener` that overrides the `onBeforeSave` method. When the event is dispatched, your listener will be called and passed the domain object and the converted `com.mongodb.DBObject`.
To intercept an object before it goes into the database, you'd register a subclass of `org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener` that overrides the `onBeforeSave` method. When the event is dispatched, your listener will be called and passed the domain object and the converted `com.mongodb.Document`.
====
[source,java]
@ -2265,11 +2264,11 @@ Simply declaring these beans in your Spring ApplicationContext will cause them t
@@ -2265,11 +2264,11 @@ Simply declaring these beans in your Spring ApplicationContext will cause them t
The list of callback methods that are present in AbstractMappingEventListener are
* `onBeforeConvert` - called in MongoTemplate insert, insertList and save operations before the object is converted to a DBObject using a MongoConveter.
* `onBeforeSave` - called in MongoTemplate insert, insertList and save operations *before* inserting/saving the DBObject in the database.
* `onAfterSave` - called in MongoTemplate insert, insertList and save operations *after* inserting/saving the DBObject in the database.
* `onAfterLoad` - called in MongoTemplate find, findAndRemove, findOne and getCollection methods after the DBObject is retrieved from the database.
* `onAfterConvert` - called in MongoTemplate find, findAndRemove, findOne and getCollection methods after the DBObject retrieved from the database was converted to a POJO.
* `onBeforeConvert` - called in MongoTemplate insert, insertList and save operations before the object is converted to a Document using a MongoConveter.
* `onBeforeSave` - called in MongoTemplate insert, insertList and save operations *before* inserting/saving the Document in the database.
* `onAfterSave` - called in MongoTemplate insert, insertList and save operations *after* inserting/saving the Document in the database.
* `onAfterLoad` - called in MongoTemplate find, findAndRemove, findOne and getCollection methods after the Document is retrieved from the database.
* `onAfterConvert` - called in MongoTemplate find, findAndRemove, findOne and getCollection methods after the Document retrieved from the database was converted to a POJO.
[[mongo.exception]]
== Exception Translation
@ -2303,9 +2302,9 @@ Here is an example that uses the `CollectionCallback` to return information abou
@@ -2303,9 +2302,9 @@ Here is an example that uses the `CollectionCallback` to return information abou
----
boolean hasIndex = template.execute("geolocation", new CollectionCallbackBoolean>() {
public Boolean doInCollection(Venue.class, DBCollection collection) throws MongoException, DataAccessException {
@ -2386,7 +2385,7 @@ class GridFsClient {
@@ -2386,7 +2385,7 @@ class GridFsClient {
----
====
The `store(…)` operations take an `InputStream`, a filename and optionally metadata information about the file to store. The metadata can be an arbitrary object which will be marshaled by the `MongoConverter` configured with the `GridFsTemplate`. Alternatively you can also provide a `DBObject` as well.
The `store(…)` operations take an `InputStream`, a filename and optionally metadata information about the file to store. The metadata can be an arbitrary object which will be marshaled by the `MongoConverter` configured with the `GridFsTemplate`. Alternatively you can also provide a `Document` as well.
Reading files from the filesystem can either be achieved through the `find(…)` or `getResources(…)` methods. Let's have a look at the `find(…)` methods first. You can either find a single file matching a `Query` or multiple ones. To easily define file queries we provide the `GridFsCriteria` helper class. It provides static factory methods to encapsulate default metadata fields (e.g. `whereFilename()`, `whereContentType()`) or the custom one through `whereMetaData()`.