Use DBRefs instead of DBObjects so that save() will work. Now requires that a Mongo instance be set on the MappingMongoConverter, which is done from afterPropertiesSet() on the template.

This commit is contained in:
Jon Brisbin
2011-03-16 08:48:25 -05:00
committed by J. Brisbin
parent b6c3760e78
commit 74df4349ed
5 changed files with 94 additions and 37 deletions

View File

@@ -23,7 +23,16 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.mongodb.*;
import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.mongodb.WriteResult;
import com.mongodb.util.JSON;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -35,7 +44,7 @@ import org.springframework.core.convert.ConversionFailedException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.document.mongodb.MongoPropertyDescriptors.MongoPropertyDescriptor;
import org.springframework.data.document.mongodb.convert.MongoConverter;
import org.springframework.data.document.mongodb.convert.MappingMongoConverter;
import org.springframework.data.document.mongodb.convert.MongoConverter;
import org.springframework.data.document.mongodb.convert.SimpleMongoConverter;
import org.springframework.data.document.mongodb.query.IndexDefinition;
@@ -1030,6 +1039,10 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
createCollection(getDefaultCollectionName(), null);
}
}
if (null != mongoConverter && mongoConverter instanceof MappingMongoConverter) {
((MappingMongoConverter) mongoConverter).setMongo(mongo);
((MappingMongoConverter) mongoConverter).setDefaultDatabase(databaseName);
}
}
@@ -1123,12 +1136,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
}
}
public void setMongoConverter(MongoConverter converter) {
this.mongoConverter = converter;
}
public void setWriteResultChecking(WriteResultChecking resultChecking) {
this.writeResultChecking = resultChecking;
}
public void setMongoConverter(MongoConverter converter) {
this.mongoConverter = converter;
}
public void setWriteResultChecking(WriteResultChecking resultChecking) {
this.writeResultChecking = resultChecking;
}
}

View File

@@ -19,12 +19,19 @@ package org.springframework.data.document.mongodb.convert;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
import com.mongodb.Mongo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.types.ObjectId;
@@ -40,7 +47,12 @@ import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.mapping.AssociationHandler;
import org.springframework.data.mapping.MappingBeanHelper;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.model.*;
import org.springframework.data.mapping.model.Association;
import org.springframework.data.mapping.model.MappingContext;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.PersistentEntity;
import org.springframework.data.mapping.model.PersistentProperty;
import org.springframework.data.mapping.model.PreferredConstructor;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -59,6 +71,8 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
protected ApplicationContext applicationContext;
protected boolean autowirePersistentBeans = false;
protected boolean useFieldAccessOnly = true;
protected Mongo mongo;
protected String defaultDatabase;
public MappingMongoConverter() {
initializeConverters();
@@ -87,6 +101,22 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
this.mappingContext = mappingContext;
}
public Mongo getMongo() {
return mongo;
}
public void setMongo(Mongo mongo) {
this.mongo = mongo;
}
public String getDefaultDatabase() {
return defaultDatabase;
}
public void setDefaultDatabase(String defaultDatabase) {
this.defaultDatabase = defaultDatabase;
}
public boolean isAutowirePersistentBeans() {
return autowirePersistentBeans;
}
@@ -369,10 +399,8 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
Collection<?> coll = (type.isArray() ? Arrays.asList((Object[]) obj) : (Collection<?>) obj);
for (Object propObjItem : coll) {
if (null != dbref) {
DBObject dbRefObj = createDBRef(propObjItem, dbref);
if (null != dbRefObj) {
dbList.add(dbRefObj);
}
DBRef dbRef = createDBRef(propObjItem, dbref);
dbList.add(dbRef);
} else {
BasicDBObject propDbObj = new BasicDBObject();
write(propObjItem, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation()));
@@ -386,10 +414,8 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
dbo.put(name, mapDbObj);
} else {
if (null != dbref) {
DBObject dbRefObj = createDBRef(obj, dbref);
if (null != dbRefObj) {
dbo.put(name, dbRefObj);
}
DBRef dbRef = createDBRef(obj, dbref);
dbo.put(name, dbRef);
} else {
BasicDBObject propDbObj = new BasicDBObject();
write(obj, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation()));
@@ -426,36 +452,37 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
}
}
protected DBObject createDBRef(Object target, org.springframework.data.document.mongodb.mapping.DBRef dbref) {
protected DBRef createDBRef(Object target, org.springframework.data.document.mongodb.mapping.DBRef dbref) {
PersistentEntity<?> targetEntity = mappingContext.getPersistentEntity(target.getClass());
if (null == targetEntity || null == targetEntity.getIdProperty()) {
return null;
}
DBObject dbo = new BasicDBObject();
PersistentProperty idProperty = targetEntity.getIdProperty();
ObjectId id = null;
try {
id = MappingBeanHelper.getProperty(target, idProperty, ObjectId.class, useFieldAccessOnly);
if (null == id) {
throw new MappingException("Cannot create a reference to an object with a NULL id.");
}
} catch (IllegalAccessException e) {
throw new MappingException(e.getMessage(), e);
} catch (InvocationTargetException e) {
throw new MappingException(e.getMessage(), e);
}
dbo.put("$id", id);
String collection = dbref.collection();
if ("".equals(collection)) {
collection = targetEntity.getType().getSimpleName().toLowerCase();
}
dbo.put("$ref", collection);
String db = dbref.db();
if (!"".equals(db)) {
dbo.put("$db", db);
String dbname = dbref.db();
if ("".equals(dbname)) {
dbname = defaultDatabase;
}
return dbo;
DB db = mongo.getDB(dbname);
return new DBRef(db, collection, id);
}
@SuppressWarnings({"unchecked"})
@@ -510,13 +537,9 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
// It's a complex object, have to read it in
if (dbo.containsField("_class")) {
try {
Class<?> clazz = Class.forName(dbo.get("_class").toString());
dbo.removeField("_class");
o = read(clazz, (DBObject) dbObj);
} catch (ClassNotFoundException e) {
throw new MappingException(e.getMessage(), e);
}
Class<?> toType = findTypeToBeUsed((DBObject) dbObj);
dbo.removeField("_class");
o = read(toType, (DBObject) dbObj);
} else {
o = read(mappingContext.getPersistentEntity(prop.getTypeInformation()), (DBObject) dbObj);
}

View File

@@ -16,12 +16,10 @@
package org.springframework.data.document.mongodb.mapping;
import java.io.Serializable;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
public class Address implements Serializable {
public class Address {
private String[] lines;
private String city;

View File

@@ -1,3 +1,19 @@
/*
* 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 static org.hamcrest.CoreMatchers.is;

View File

@@ -134,6 +134,13 @@ public class MappingTests {
p.setAccounts(accounts);
template.insert("person", p);
Account newAcct = new Account();
newAcct.setBalance(10000.00f);
template.insert("account", newAcct);
accounts.add(newAcct);
template.save("person", p);
assertNotNull(p.getId());
}