Files
spring-data-mongodb/src/docbkx/reference/mapping.xml

179 lines
6.8 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="mongo.mapping">
<title>Mapping support</title>
<para>The object mapping support for MongoDB
</para>
<section id="mongodb:mapping-configuration">
<title>MongoDB Mapping Configuration</title>
<para>Spring's Mongo namespace enables you to easily enable mapping functionality</para>
<example>
<title>XML schema to configure MongoDB mapping support</title>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<beans>
<!-- Default bean name is 'mongo' -->
<mongo:mongo host="localhost" port="27017"/>
<!-- by default look for a Mongo object named 'mongo' -->
<mongo:mapping-converter base-package="com.mycompany.domain" autowire="true"/>
</beans]]>
</programlisting>
</example>
<para>This sets up the right objects in the ApplicationContext to perform the full gamut
of mapping operations. The <code>base-package</code> property tells it where to scan for
classes annotated with the <classname>@org.springframework.data.document.mongodb.mapping.Document</classname>
annotation and the <code>autowire</code> property tells it whether to pass mapped domain objects through the
Spring ApplicationContext's autowiring mechanism, allowing you to use
<classname>@org.springframework.beans.factory.annotation.Autowired</classname> inside your domain objects.
</para>
</section>
<section id="mongodb:mapping-usage">
<title>Mapping Framework Usage</title>
<para>To take full advantage of the object mapping functionality inside the Spring Data/MongoDB support,
you should annotate your mapped objects with the <classname>@org.springframework.data.document.mongodb.mapping.Document</classname>
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.
</para>
<example>
<title>Example domain object</title>
<programlisting language="java"><![CDATA[package com.mycompany.domain;
@Document
public class Person {
@Id
private ObjectId id;
@Indexed
private Integer ssn;
private String firstName;
@Indexed
private String lastName;
}]]>
</programlisting>
</example>
<important>
<para>The <classname>@Id</classname> annotation tells the mapper which property you want to use for the
MongoDB <code>_id</code> property and the <classname>@Indexed</classname> annotation tells the mapping
framework to call <code>ensureIndex</code> on that property of your document, making searches faster.
</para>
</important>
<section id="mongodb:mapping-usage:indexes">
<title>Compound Indexes</title>
<para>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 <code>lastName</code> in ascending order
and <code>age</code> in descending order:
<example>
<title>Example Compound Index Usage</title>
<programlisting language="java"><![CDATA[package com.mycompany.domain;
@Document
@CompoundIndexes({
@CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}")
})
public class Person {
@Id
private ObjectId id;
private Integer age;
private String firstName;
private String lastName;
}]]>
</programlisting>
</example>
</para>
</section>
<section id="mongodb:mapping-usage:references">
<title>Using DBRefs</title>
<para>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.
</para>
<para>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):
</para>
<example>
<title>Child object referred to using a DBRef</title>
<programlisting language="java"><![CDATA[
@Document
public class Account {
@Id
private ObjectId id;
private Float total;
}
@Document
public class Person {
@Id
private ObjectId id;
@Indexed
private Integer ssn;
@DBRef
private List<Account> accounts;
}]]>
</programlisting>
</example>
<para>There's no need to use something like <code>@OneToMany</code> 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 <code>Account</code> objects themselves.
<important>
<para>The mapping framework does not handle cascading saves. If you change an <code>Account</code> object that is
referenced by a <code>Person</code> object, you must save the Account object separately. Calling <code>save</code>
on the <code>Person</code> object will not automatically save the <code>Account</code> objects in the
property <code>accounts</code>.</para>
</important>
</para>
</section>
<section id="mongodb:mapping-usage:events">
<title>Handling Mapping Framework Events</title>
<para>Built into the MongoDB mapping framework are several <classname>org.springframework.context.ApplicationEvent</classname>
events that your application can respond to
</para>
</section>
</section>
</chapter>