You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
686 lines
26 KiB
686 lines
26 KiB
<?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="mapping-chapter"> |
|
<title>Mapping</title> |
|
|
|
<para>Rich maping support is provided by the |
|
<classname>MongoMappingConverter</classname>. |
|
<classname>MongoMappingConverter</classname> has a rich metadata model that |
|
provides a full feature set of functionality to map domain objects to |
|
MongoDB documents.The mapping metadata model is populated using annotations |
|
on your domain objects. However, the infrastructure is not limited to using |
|
annotations as the only source of metadata information. The |
|
<classname>MongoMappingConverter</classname> also allows you to map objects |
|
to documents without providing any additional metadata, by following a set |
|
of conventions.</para> |
|
|
|
<para>In this section we will describe the features of the |
|
MongoMappingConverter. How to use conventions for mapping objects to |
|
documents and how to override those conventions with annotation based |
|
mapping metadata.</para> |
|
|
|
<note> |
|
<para><classname>SimpleMongoConverter</classname> has been deprecated in |
|
Spring Data MongoDB M3 as all of its functionality has been subsumed into |
|
<classname>MappingMongoConverter</classname>.</para> |
|
</note> |
|
|
|
<section id="mapping-conventions"> |
|
<title>Convention based Mapping</title> |
|
|
|
<para><classname>MongoMappingConverter</classname> has a few conventions |
|
for mapping objects to documents when no additional mapping metadata is |
|
provided. The conventions are:</para> |
|
|
|
<itemizedlist> |
|
<listitem> |
|
<para>The short Java class name is mapped to the collection name in |
|
the following manner. The class |
|
'<classname>com.bigbank.SavingsAccount</classname>' maps to |
|
'<literal>savingsAccount</literal>' collection name.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>All nested objects are stored as nested objects in the document |
|
and *not* as DBRefs</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>The converter will use any Spring Converters registered with it |
|
to override the default mapping of object properties to document |
|
field/values.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>The fields of an object are used to convert to and from fields |
|
in the document. Public JavaBean properties are not used.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>You can have a single non-zero argument constructor whose |
|
constructor argument names match top level field names of document, |
|
that constructor will be used. Otherewise the zero arg constructor |
|
will be used. if there is more than one non-zero argument constructor |
|
an exception will be thrown.</para> |
|
</listitem> |
|
</itemizedlist> |
|
|
|
<section> |
|
<title>How the '_id' field is handled in the mapping layer</title> |
|
|
|
<para>MongoDB requires that you have an '_id' field for all documents. |
|
If you don't provide one the driver will assign a ObjectId with a |
|
generated value. The "_id" field can be of any type the, other than |
|
arrays, so long as it is unique. The driver naturally supports all |
|
primitive types and Dates. When using the |
|
<classname>MongoMappingConverter</classname> there are certain rules |
|
that govern how properties from the Java class is mapped to this '_id' |
|
field.</para> |
|
|
|
<para>The following outlines what field will be mapped to the '_id' |
|
document field:</para> |
|
|
|
<para><itemizedlist> |
|
<listitem> |
|
<para>A field annotated with <classname>@Id</classname> |
|
(<classname>org.springframework.data.annotation.Id</classname>) |
|
will be mapped to the '_id' field.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>A field without an annotation but named |
|
<classname>id</classname> will be mapped to the '_id' |
|
field.</para> |
|
</listitem> |
|
</itemizedlist></para> |
|
|
|
<para>The following outlines what type conversion, if any, will be done |
|
on the property mapped to the _id document field.</para> |
|
|
|
<itemizedlist> |
|
<listitem> |
|
<para>If a field named 'id' is declared as a String or BigInteger in |
|
the Java class it will be converted to and stored as an ObjectId if |
|
possible. ObjectId as a field type is also valid. If you specify a |
|
value for 'id' in your application, the conversion to an ObjectId is |
|
delected to the MongoDBdriver. If the specified 'id' value cannot be |
|
converted to an ObjectId, then the value will be stored as is in the |
|
document's _id field.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>If a field named ' id' id field is not declared as a String, |
|
BigInteger, or ObjectID in the Java class then you should assign it |
|
a value in your application so it can be stored 'as-is' in the |
|
document's _id field.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>If no field named 'id' is present in the Java class then an |
|
implicit '_id' file will be generated by the driver but not mapped |
|
to a property or field of the Java class.</para> |
|
</listitem> |
|
</itemizedlist> |
|
|
|
<para>When querying and updating <classname>MongoTemplate</classname> |
|
will use the converter to handle conversions of the |
|
<classname>Query</classname> and <classname>Update</classname> objects |
|
that correspond to the above rules for saving documents so field names |
|
and types used in your queries will be able to match what is in your |
|
domain classes.</para> |
|
</section> |
|
</section> |
|
|
|
<section id="mapping-configuration"> |
|
<title>Mapping Configuration</title> |
|
|
|
<para>Unless explicitly configured, an instance of |
|
<classname>MongoMappingConverter</classname> is created by default when |
|
creating a <classname>MongoTemplate</classname>. You can create your own |
|
instance of the <classname>MappingMongoConverter</classname> so as to tell |
|
it where to scan the classpath at startup your domain classes in order to |
|
extract metadata and construct indexes. Also, by creating your own |
|
instance you can register Spring converters to use for mapping specific |
|
classes to and from the database.</para> |
|
|
|
<para>You can configure the <classname>MongoMappingConverter</classname> |
|
as well as <classname>com.mongodb.Mongo</classname> and MongoTemplate |
|
either using Java or XML based metadata. Here is an example using Spring's |
|
Java based configuration</para> |
|
|
|
<example> |
|
<title>@Configuration class to configure MongoDB mapping support</title> |
|
|
|
<programlisting language="java">@Configuration |
|
public class GeoSpatialAppConfig extends AbstractMongoConfiguration { |
|
|
|
@Bean |
|
public Mongo mongo() throws Exception { |
|
return new Mongo("localhost"); |
|
} |
|
|
|
@Override |
|
public String getDatabaseName() { |
|
return "database"; |
|
} |
|
|
|
@Override |
|
public String getMappingBasePackage() { |
|
return "com.bigbank.domain"; |
|
} |
|
|
|
// the following are optional |
|
|
|
@Override |
|
protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) { |
|
Set<Converter<?, ?>> converterList = new HashSet<Converter<?, ?>>(); |
|
converterList.add(new org.springframework.data.mongodb.test.PersonReadConverter()); |
|
converterList.add(new org.springframework.data.mongodb.test.PersonWriteConverter()); |
|
converter.setCustomConverters(converterList); |
|
} |
|
|
|
@Bean |
|
public LoggingEventListener<MongoMappingEvent> mappingEventsListener() { |
|
return new LoggingEventListener<MongoMappingEvent>(); |
|
} |
|
|
|
}</programlisting> |
|
</example> |
|
|
|
<para><classname>AbstractMongoConfiguration</classname> requires you to |
|
implement methods that define a <classname>com.mongodb.Mongo</classname> |
|
as well as provide a database name. |
|
<classname>AbstractMongoConfiguration</classname> also has a method you |
|
can override named '<methodname>getMappingBasePackage</methodname>' which |
|
tells the converter where to scan for classes annotated with the |
|
<classname>@org.springframework.data.mongodb.core.mapping.Document</classname> |
|
annotation.</para> |
|
|
|
<para>You can add additional converters to the converter by overriding the |
|
method afterMappingMongoConverterCreation. Also shown in the above example |
|
is a <classname>LoggingEventListener</classname> which logs |
|
<classname>MongoMappingEvent</classname>s that are posted onto Spring's |
|
<interfacename>ApplicationContextEvent</interfacename> |
|
infrastructure.</para> |
|
|
|
<note> |
|
<para>AbstractMongoConfiguration will create a MongoTemplate instance |
|
and registered with the container under the name 'mongoTemplate'.</para> |
|
</note> |
|
|
|
<para>You can also override the method <literal>UserCredentials |
|
getUserCredentials()</literal> to provide the username and password |
|
information to connect to the database.</para> |
|
|
|
<para>Spring's MongoDB namespace enables you to easily enable mapping |
|
functionality in XML</para> |
|
|
|
<example> |
|
<title>XML schema to configure MongoDB mapping support</title> |
|
|
|
<programlisting language="xml"><?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"> |
|
|
|
<!-- Default bean name is 'mongo' --> |
|
<mongo:mongo host="localhost" port="27017"/> |
|
|
|
<mongo:db-factory dbname="database" mongo-ref="mongo"/> |
|
|
|
<!-- by default look for a Mongo object named 'mongo' - default name used for the converter is 'mappingConverter' --> |
|
<mongo:mapping-converter base-package="com.bigbank.domain"> |
|
<mongo:custom-converters> |
|
<mongo:converter ref="readConverter"/> |
|
<mongo:converter> |
|
<bean class="org.springframework.data.mongodb.test.PersonWriteConverter"/> |
|
</mongo:converter> |
|
</mongo:custom-converters> |
|
</mongo:mapping-converter> |
|
|
|
<bean id="readConverter" class="org.springframework.data.mongodb.test.PersonReadConverter"/> |
|
|
|
<!-- set the mapping converter to be used by the MongoTemplate --> |
|
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> |
|
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> |
|
<constructor-arg name="mongoConverter" ref="mappingConverter"/> |
|
</bean> |
|
|
|
<bean class="org.springframework.data.mongodb.core.mapping.event.LoggingEventListener"/> |
|
|
|
</beans |
|
</programlisting> |
|
</example> |
|
|
|
<para>The <code>base-package</code> property tells it where to scan for |
|
classes annotated with the |
|
<classname>@org.springframework.data.mongodb.core.mapping.Document</classname> |
|
annotation.</para> |
|
</section> |
|
|
|
<section id="mapping-usage"> |
|
<title>Metadata based Mapping</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.mongodb.core.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">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="mapping-usage-annotations"> |
|
<title>Mapping annotation overview</title> |
|
|
|
<para>The MappingMongoConverter can use metadata to drive the mapping of |
|
objects to documents. An overview of the annotations is provided |
|
below</para> |
|
|
|
<itemizedlist> |
|
<listitem> |
|
<para><literal>@Id </literal>- applied at the field level to mark |
|
the field used for identiy purpose.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@Document</literal> - applied at the class level to |
|
indicate this class is a candidate for mapping to the database. You |
|
can specify the name of the collection where the database will be |
|
stored.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@DBRef</literal> - applied at the field to indicate |
|
it is to be stored using a com.mongodb.DBRef.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@Indexed</literal> - applied at the field level to |
|
describe how to index the field.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@CompoundIndex</literal> - applied at the type level |
|
to declare Compound Indexes</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@GeoSpatialIndexed</literal> - applied at the field |
|
level to describe how to geoindex the field.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@Transient</literal> - 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</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@PersistenceConstructor</literal> - 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.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@Value</literal> - 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: <code>@Value("#root.myProperty")</code> where |
|
<literal>root</literal> refers to the root of the given |
|
document.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para><literal>@Field</literal> - 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.</para> |
|
</listitem> |
|
</itemizedlist> |
|
|
|
<para>The mapping metadata infrastructure is defined in a seperate |
|
spring-data-commons project that is technology agnostic. Specific |
|
subclasses are using in the MongoDB support to support annotation based |
|
metadata. Other strategies are also possible to put in place if there is |
|
demand.</para> |
|
|
|
<para>Here is an example of a more complex mapping.</para> |
|
|
|
<programlisting language="java">@Document |
|
@CompoundIndexes({ |
|
@CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}") |
|
}) |
|
public class Person<T extends Address> { |
|
|
|
@Id |
|
private String id; |
|
|
|
@Indexed(unique = true) |
|
private Integer ssn; |
|
|
|
@Field("fName") |
|
private String firstName; |
|
|
|
@Indexed |
|
private String lastName; |
|
|
|
private Integer age; |
|
|
|
@Transient |
|
private Integer accountTotal; |
|
|
|
@DBRef |
|
private List<Account> accounts; |
|
|
|
private T address; |
|
|
|
|
|
public Person(Integer ssn) { |
|
this.ssn = ssn; |
|
} |
|
|
|
@PersistenceConstructor |
|
public Person(Integer ssn, String firstName, String lastName, Integer age, T address) { |
|
this.ssn = ssn; |
|
this.firstName = firstName; |
|
this.lastName = lastName; |
|
this.age = age; |
|
this.address = address; |
|
} |
|
|
|
public String getId() { |
|
return id; |
|
} |
|
|
|
// no setter for Id. (getter is only exposed for some unit testing) |
|
|
|
public Integer getSsn() { |
|
return ssn; |
|
} |
|
|
|
|
|
// other getters/setters ommitted |
|
</programlisting> |
|
|
|
<para/> |
|
</section> |
|
|
|
<section id="mapping-custom-object-construction"> |
|
<title>Customized Object Construction</title> |
|
|
|
<para>The Mapping Subsystem allows the customization of the object |
|
construction by annotating a constructor with the |
|
<literal>@PersistenceConstructor</literal> annotation. The values to be |
|
used for the constructor parameters are resolved in the following |
|
way:</para> |
|
|
|
<itemizedlist> |
|
<listitem> |
|
<para>If a parameter is annotated with the <code>@Value</code> |
|
annotation, the given expression is evaluated and the result is used |
|
as the parameter value.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>If the Java type has a property whose name matches the given |
|
field of the input document, then it's property information is used |
|
to select the appropriate constructor parameter to pass the input |
|
field value to. This works only if the parameter name information is |
|
present in the java .class files which can be achieved by compiling |
|
the source with debug information or using the new |
|
<literal>-parameters</literal> command-line switch for javac in Java |
|
8.</para> |
|
</listitem> |
|
|
|
<listitem> |
|
<para>Otherwise an <classname>MappingException</classname> will be |
|
thrown indicating that the given constructor parameter could not be |
|
bound.</para> |
|
</listitem> |
|
</itemizedlist> |
|
|
|
<programlisting language="java">class OrderItem { |
|
|
|
@Id String id; |
|
int quantity; |
|
double unitPrice; |
|
|
|
OrderItem(String id, @Value("#root.qty ?: 0") int quantity, double unitPrice) { |
|
this.id = id; |
|
this.quantity = quantity; |
|
this.unitPrice = unitPrice; |
|
} |
|
|
|
// getters/setters ommitted |
|
} |
|
|
|
DBObject input = new BasicDBObject("id", "4711"); |
|
input.put("unitPrice", 2.5); |
|
input.put("qty",5); |
|
OrderItem item = converter.read(OrderItem.class, input);</programlisting> |
|
|
|
<note> |
|
<para>The SpEL expression in the <literal>@Value</literal> annotation |
|
of the <literal>quantity</literal> parameter falls back to the value |
|
<literal>0</literal> if the given property path cannot be |
|
resolved.</para> |
|
</note> |
|
|
|
<para>Additional examples for using the |
|
<classname>@PersistenceConstructor</classname> annotation can be found |
|
in the <ulink |
|
url="https://github.com/spring-projects/spring-data-mongodb/blob/master/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java">MappingMongoConverterUnitTests</ulink> |
|
test suite.</para> |
|
</section> |
|
|
|
<section id="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.</para> |
|
|
|
<note> |
|
<para>Compound indexes are very important to improve the performance |
|
of queries that involve criteria on multiple fields</para> |
|
</note> |
|
|
|
<para>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">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="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> |
|
<programlisting language="java"> |
|
@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="mapping-usage-events"> |
|
<title>Mapping Framework Events</title> |
|
|
|
<para>Events are fired throughout the lifecycle of the mapping process. |
|
This is described in the <link |
|
linkend="mongodb.mapping-usage.events">Lifecycle Events</link> |
|
section.</para> |
|
|
|
<para>Simply declaring these beans in your Spring ApplicationContext |
|
will cause them to be invoked whenever the event is dispatched.</para> |
|
</section> |
|
|
|
<section id="mapping-explicit-converters"> |
|
<title>Overriding Mapping with explicit Converters</title> |
|
|
|
<para>When storing and querying your objects it is convenient to have a |
|
<interfacename>MongoConverter</interfacename> instance handle the |
|
mapping of all Java types to DBObjects. However, sometimes you may want |
|
the <interfacename>MongoConverter</interfacename>'s do most of the work |
|
but allow you to selectivly handle the conversion for a particular type |
|
or to optimize performance.</para> |
|
|
|
<para>To selectivly handle the conversion yourself, register one or more |
|
one or more |
|
<classname>org.springframework.core.convert.converter.Converter</classname> |
|
instances with the MongoConverter.</para> |
|
|
|
<note> |
|
<para>Spring 3.0 introduced a core.convert package that provides a |
|
general type conversion system. This is described in detail in the |
|
Spring reference documentation section entitled <ulink |
|
url="http://docs.spring.io/spring/docs/3.0.x/reference/validation.html#core-convert">Spring |
|
3 Type Conversion</ulink>.</para> |
|
</note> |
|
|
|
<para>The <methodname>setConverters</methodname> method on |
|
<classname>SimpleMongoConverter</classname> and |
|
<classname>MappingMongoConverter</classname> should be used for this |
|
purpose. The method |
|
<methodname>afterMappingMongoConverterCreation</methodname> in |
|
<classname>AbstractMongoConfiguration</classname> can be overriden to |
|
configure a MappingMongoConverter. The examples <link |
|
linkend="???">here</link> at the begining of this chapter show how to |
|
perform the configuration using Java and XML.</para> |
|
|
|
<para>Below is an example of a Spring Converter implementation that |
|
converts from a DBObject to a Person POJO.</para> |
|
|
|
<programlisting language="java">public class PersonReadConverter implements Converter<DBObject, Person> { |
|
|
|
public Person convert(DBObject source) { |
|
Person p = new Person((ObjectId) source.get("_id"), (String) source.get("name")); |
|
p.setAge((Integer) source.get("age")); |
|
return p; |
|
} |
|
|
|
}</programlisting> |
|
|
|
<para>Here is an example that converts from a Person to a |
|
DBObject.</para> |
|
|
|
<programlisting language="java">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; |
|
} |
|
|
|
}</programlisting> |
|
|
|
<para/> |
|
</section> |
|
</section> |
|
</chapter>
|
|
|