Fix for array primitives, pushing first bit of documentation
This commit is contained in:
@@ -413,7 +413,12 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
|||||||
Class<?> type = prop.getType();
|
Class<?> type = prop.getType();
|
||||||
if (prop.isCollection()) {
|
if (prop.isCollection()) {
|
||||||
BasicDBList dbList = new BasicDBList();
|
BasicDBList dbList = new BasicDBList();
|
||||||
Collection<?> coll = (type.isArray() ? Arrays.asList((Object[]) obj) : (Collection<?>) obj);
|
Collection<?> coll;
|
||||||
|
if (type.isArray()) {
|
||||||
|
coll = Arrays.asList((Object[]) obj);
|
||||||
|
} else {
|
||||||
|
coll = (Collection<?>) obj;
|
||||||
|
}
|
||||||
for (Object propObjItem : coll) {
|
for (Object propObjItem : coll) {
|
||||||
if (null != dbref) {
|
if (null != dbref) {
|
||||||
DBRef dbRef = createDBRef(propObjItem, dbref);
|
DBRef dbRef = createDBRef(propObjItem, dbref);
|
||||||
@@ -569,7 +574,7 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
|||||||
}
|
}
|
||||||
return Arrays.asList(items);
|
return Arrays.asList(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<?> toType = findTypeToBeUsed((DBObject) dbObj);
|
Class<?> toType = findTypeToBeUsed((DBObject) dbObj);
|
||||||
|
|
||||||
// It's a complex object, have to read it in
|
// It's a complex object, have to read it in
|
||||||
@@ -594,11 +599,11 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
|
|||||||
*/
|
*/
|
||||||
protected Class<?> findTypeToBeUsed(DBObject dbObject) {
|
protected Class<?> findTypeToBeUsed(DBObject dbObject) {
|
||||||
Object classToBeUsed = dbObject.get(CUSTOM_TYPE_KEY);
|
Object classToBeUsed = dbObject.get(CUSTOM_TYPE_KEY);
|
||||||
|
|
||||||
if (classToBeUsed == null) {
|
if (classToBeUsed == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Class.forName(classToBeUsed.toString());
|
return Class.forName(classToBeUsed.toString());
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class MongoMappingContext extends BasicMappingContext {
|
|||||||
simpleTypes.add(com.mongodb.DBRef.class);
|
simpleTypes.add(com.mongodb.DBRef.class);
|
||||||
simpleTypes.add(ObjectId.class);
|
simpleTypes.add(ObjectId.class);
|
||||||
simpleTypes.add(CodeWScope.class);
|
simpleTypes.add(CodeWScope.class);
|
||||||
|
simpleTypes.add(Character.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 by the original author(s).
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.data.document.mongodb.mapping;
|
||||||
|
|
||||||
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jon Brisbin <jbrisbin@vmware.com>
|
||||||
|
*/
|
||||||
|
@Document
|
||||||
|
public class Location {
|
||||||
|
|
||||||
|
private ObjectId id;
|
||||||
|
private double[] latlong;
|
||||||
|
private int[] numbers;
|
||||||
|
private float[] amounts;
|
||||||
|
|
||||||
|
public Location(double[] latlong, int[] numbers, float[] amounts) {
|
||||||
|
this.latlong = latlong;
|
||||||
|
this.numbers = numbers;
|
||||||
|
this.amounts = amounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectId getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[] getLatlong() {
|
||||||
|
return latlong;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLatlong(double[] latlong) {
|
||||||
|
this.latlong = latlong;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getNumbers() {
|
||||||
|
return numbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumbers(int[] numbers) {
|
||||||
|
this.numbers = numbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getAmounts() {
|
||||||
|
return amounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmounts(float[] amounts) {
|
||||||
|
this.amounts = amounts;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -162,4 +162,17 @@ public class MappingTests {
|
|||||||
assertThat(result.size(), is(1));
|
assertThat(result.size(), is(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrimitives() {
|
||||||
|
Location loc = new Location(
|
||||||
|
new double[]{1.0, 2.0},
|
||||||
|
new int[]{1, 2, 3, 4},
|
||||||
|
new float[]{1.0f, 2.0f}
|
||||||
|
);
|
||||||
|
template.insert("locations", loc);
|
||||||
|
|
||||||
|
List<Location> result = template.find("locations", new Query(Criteria.where("_id").is(loc.getId())), Location.class);
|
||||||
|
assertThat(result.size(), is(1));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
<firstname>Costin</firstname>
|
<firstname>Costin</firstname>
|
||||||
<surname>Leau</surname>
|
<surname>Leau</surname>
|
||||||
</author>
|
</author>
|
||||||
|
<author>
|
||||||
|
<firstname>Jon</firstname>
|
||||||
|
<surname>Brisbin</surname>
|
||||||
|
</author>
|
||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<legalnotice>
|
<legalnotice>
|
||||||
@@ -57,6 +61,7 @@
|
|||||||
<xi:include href="reference/introduction.xml"/>
|
<xi:include href="reference/introduction.xml"/>
|
||||||
<xi:include href="reference/mongodb.xml"/>
|
<xi:include href="reference/mongodb.xml"/>
|
||||||
<xi:include href="reference/mongo-repositories.xml"/>
|
<xi:include href="reference/mongo-repositories.xml"/>
|
||||||
|
<xi:include href="reference/mapping.xml"/>
|
||||||
<xi:include href="reference/jmx.xml"/>
|
<xi:include href="reference/jmx.xml"/>
|
||||||
</part>
|
</part>
|
||||||
|
|
||||||
|
|||||||
178
src/docbkx/reference/mapping.xml
Normal file
178
src/docbkx/reference/mapping.xml
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<?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>
|
||||||
Reference in New Issue
Block a user