Mapping support
The object mapping support for MongoDB
MongoDB Mapping Configuration
Spring's Mongo namespace enables you to easily enable mapping functionality
XML schema to configure MongoDB mapping support
This sets up the right objects in the ApplicationContext to perform the full gamut
of mapping operations. The base-package property tells it where to scan for
classes annotated with the @org.springframework.data.document.mongodb.mapping.Document
annotation and the autowire property tells it whether to pass mapped domain objects through the
Spring ApplicationContext's autowiring mechanism, allowing you to use
@org.springframework.beans.factory.annotation.Autowired inside your domain objects.
Mapping Framework Usage
To take full advantage of the object mapping functionality inside the Spring Data/MongoDB support,
you should annotate your mapped objects with the @org.springframework.data.document.mongodb.mapping.Document
annotation. Although it is not necessary for the mapping framework to have this annotation (your POJOs
will be mapped correctly, even without any annotations), it allows the classpath scanner to find and
pre-process your domain objects to extract the necessary metadata. If you don't use this annotation,
your application will take a slight performance hit the first time you store a domain object because the
mapping framework needs to build up its internal metadata model so it knows about the properties of your
domain object and how to persist them.
Example domain object
The @Id annotation tells the mapper which property you want to use for the
MongoDB _id property and the @Indexed annotation tells the mapping
framework to call ensureIndex on that property of your document, making searches faster.
Compound Indexes
Compound indexes are also supported. They are defined at the class level, rather than on indidvidual
properties. Here's an example that creates a compound index of lastName in ascending order
and age in descending order:
Example Compound Index Usage
Using DBRefs
The mapping framework doesn't have to store child objects embedded within the document. You can also
store them separately and use a DBRef to refer to that document. When the object is loaded from MongoDB,
those references will be eagerly resolved and you will get back a mapped object that looks the same as if
it had been stored embedded within your master document.
Here's an example of using a DBRef to refer to a specific document that exists independently of the
object in which it is referenced (both classes are shown in-line for brevity's sake):
accounts;
}]]>
There's no need to use something like @OneToMany because the mapping framework sees that
you're wanting a one-to-many relationship because there is a List of objects. When the object is stored
in MongoDB, there will be a list of DBRefs rather than the Account objects themselves.
The mapping framework does not handle cascading saves. If you change an Account object that is
referenced by a Person object, you must save the Account object separately. Calling save
on the Person object will not automatically save the Account objects in the
property accounts.
Handling Mapping Framework Events
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.
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 org.springframework.data.document.mongodb.mapping.event.AbstractMappingEventListener
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.
extends AbstractMappingEventListener {
@Override
public void onBeforeConvert(Person p) {
... does some auditing manipulation, set timestamps, whatever ...
}
}
]]>
To intercept an object before it goes into the database, you'd register a subclass of
org.springframework.data.document.mongodb.mapping.event.AbstractMappingEventListener
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.
extends AbstractMappingEventListener {
@Override
public void onBeforeSave(Person p, DBObject dbo) {
... change values, delete them, whatever ...
}
}
]]>
Simply declaring these beans in your Spring ApplicationContext will cause them to be invoked whenever the
event is dispatched.