Skip to content

Commit 74df434

Browse files
committed
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.
1 parent b6c3760 commit 74df434

File tree

5 files changed

+94
-37
lines changed

5 files changed

+94
-37
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java

+22-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@
2323
import java.util.List;
2424
import java.util.Set;
2525

26-
import com.mongodb.*;
26+
import com.mongodb.BasicDBObject;
27+
import com.mongodb.CommandResult;
28+
import com.mongodb.DB;
29+
import com.mongodb.DBCollection;
30+
import com.mongodb.DBCursor;
31+
import com.mongodb.DBObject;
32+
import com.mongodb.Mongo;
33+
import com.mongodb.MongoException;
34+
import com.mongodb.WriteConcern;
35+
import com.mongodb.WriteResult;
2736
import com.mongodb.util.JSON;
2837
import org.apache.commons.logging.Log;
2938
import org.apache.commons.logging.LogFactory;
@@ -35,7 +44,7 @@
3544
import org.springframework.dao.DataAccessException;
3645
import org.springframework.dao.DataIntegrityViolationException;
3746
import org.springframework.data.document.mongodb.MongoPropertyDescriptors.MongoPropertyDescriptor;
38-
import org.springframework.data.document.mongodb.convert.MongoConverter;
47+
import org.springframework.data.document.mongodb.convert.MappingMongoConverter;
3948
import org.springframework.data.document.mongodb.convert.MongoConverter;
4049
import org.springframework.data.document.mongodb.convert.SimpleMongoConverter;
4150
import org.springframework.data.document.mongodb.query.IndexDefinition;
@@ -1030,6 +1039,10 @@ public void afterPropertiesSet() {
10301039
createCollection(getDefaultCollectionName(), null);
10311040
}
10321041
}
1042+
if (null != mongoConverter && mongoConverter instanceof MappingMongoConverter) {
1043+
((MappingMongoConverter) mongoConverter).setMongo(mongo);
1044+
((MappingMongoConverter) mongoConverter).setDefaultDatabase(databaseName);
1045+
}
10331046
}
10341047

10351048

@@ -1123,12 +1136,12 @@ public T doWith(DBObject object) {
11231136
}
11241137
}
11251138

1126-
public void setMongoConverter(MongoConverter converter) {
1127-
this.mongoConverter = converter;
1128-
}
1129-
1130-
public void setWriteResultChecking(WriteResultChecking resultChecking) {
1131-
this.writeResultChecking = resultChecking;
1132-
}
1139+
public void setMongoConverter(MongoConverter converter) {
1140+
this.mongoConverter = converter;
1141+
}
1142+
1143+
public void setWriteResultChecking(WriteResultChecking resultChecking) {
1144+
this.writeResultChecking = resultChecking;
1145+
}
11331146

11341147
}

spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java

+48-25
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@
1919
import java.lang.reflect.Array;
2020
import java.lang.reflect.InvocationTargetException;
2121
import java.math.BigInteger;
22-
import java.util.*;
22+
import java.util.ArrayList;
23+
import java.util.Arrays;
24+
import java.util.Collection;
25+
import java.util.LinkedHashMap;
26+
import java.util.List;
27+
import java.util.Map;
2328

2429
import com.mongodb.BasicDBList;
2530
import com.mongodb.BasicDBObject;
31+
import com.mongodb.DB;
2632
import com.mongodb.DBObject;
2733
import com.mongodb.DBRef;
34+
import com.mongodb.Mongo;
2835
import org.apache.commons.logging.Log;
2936
import org.apache.commons.logging.LogFactory;
3037
import org.bson.types.ObjectId;
@@ -40,7 +47,12 @@
4047
import org.springframework.data.mapping.AssociationHandler;
4148
import org.springframework.data.mapping.MappingBeanHelper;
4249
import org.springframework.data.mapping.PropertyHandler;
43-
import org.springframework.data.mapping.model.*;
50+
import org.springframework.data.mapping.model.Association;
51+
import org.springframework.data.mapping.model.MappingContext;
52+
import org.springframework.data.mapping.model.MappingException;
53+
import org.springframework.data.mapping.model.PersistentEntity;
54+
import org.springframework.data.mapping.model.PersistentProperty;
55+
import org.springframework.data.mapping.model.PreferredConstructor;
4456
import org.springframework.expression.Expression;
4557
import org.springframework.expression.spel.standard.SpelExpressionParser;
4658
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -59,6 +71,8 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
5971
protected ApplicationContext applicationContext;
6072
protected boolean autowirePersistentBeans = false;
6173
protected boolean useFieldAccessOnly = true;
74+
protected Mongo mongo;
75+
protected String defaultDatabase;
6276

6377
public MappingMongoConverter() {
6478
initializeConverters();
@@ -87,6 +101,22 @@ public void setMappingContext(MappingContext mappingContext) {
87101
this.mappingContext = mappingContext;
88102
}
89103

104+
public Mongo getMongo() {
105+
return mongo;
106+
}
107+
108+
public void setMongo(Mongo mongo) {
109+
this.mongo = mongo;
110+
}
111+
112+
public String getDefaultDatabase() {
113+
return defaultDatabase;
114+
}
115+
116+
public void setDefaultDatabase(String defaultDatabase) {
117+
this.defaultDatabase = defaultDatabase;
118+
}
119+
90120
public boolean isAutowirePersistentBeans() {
91121
return autowirePersistentBeans;
92122
}
@@ -369,10 +399,8 @@ protected void writePropertyInternal(PersistentProperty prop, Object obj, DBObje
369399
Collection<?> coll = (type.isArray() ? Arrays.asList((Object[]) obj) : (Collection<?>) obj);
370400
for (Object propObjItem : coll) {
371401
if (null != dbref) {
372-
DBObject dbRefObj = createDBRef(propObjItem, dbref);
373-
if (null != dbRefObj) {
374-
dbList.add(dbRefObj);
375-
}
402+
DBRef dbRef = createDBRef(propObjItem, dbref);
403+
dbList.add(dbRef);
376404
} else {
377405
BasicDBObject propDbObj = new BasicDBObject();
378406
write(propObjItem, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation()));
@@ -386,10 +414,8 @@ protected void writePropertyInternal(PersistentProperty prop, Object obj, DBObje
386414
dbo.put(name, mapDbObj);
387415
} else {
388416
if (null != dbref) {
389-
DBObject dbRefObj = createDBRef(obj, dbref);
390-
if (null != dbRefObj) {
391-
dbo.put(name, dbRefObj);
392-
}
417+
DBRef dbRef = createDBRef(obj, dbref);
418+
dbo.put(name, dbRef);
393419
} else {
394420
BasicDBObject propDbObj = new BasicDBObject();
395421
write(obj, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation()));
@@ -426,36 +452,37 @@ protected void writeMapInternal(Map<Object, Object> obj, DBObject dbo) {
426452
}
427453
}
428454

429-
protected DBObject createDBRef(Object target, org.springframework.data.document.mongodb.mapping.DBRef dbref) {
455+
protected DBRef createDBRef(Object target, org.springframework.data.document.mongodb.mapping.DBRef dbref) {
430456
PersistentEntity<?> targetEntity = mappingContext.getPersistentEntity(target.getClass());
431457
if (null == targetEntity || null == targetEntity.getIdProperty()) {
432458
return null;
433459
}
434460

435-
DBObject dbo = new BasicDBObject();
436461
PersistentProperty idProperty = targetEntity.getIdProperty();
437462
ObjectId id = null;
438463
try {
439464
id = MappingBeanHelper.getProperty(target, idProperty, ObjectId.class, useFieldAccessOnly);
465+
if (null == id) {
466+
throw new MappingException("Cannot create a reference to an object with a NULL id.");
467+
}
440468
} catch (IllegalAccessException e) {
441469
throw new MappingException(e.getMessage(), e);
442470
} catch (InvocationTargetException e) {
443471
throw new MappingException(e.getMessage(), e);
444472
}
445-
dbo.put("$id", id);
446473

447474
String collection = dbref.collection();
448475
if ("".equals(collection)) {
449476
collection = targetEntity.getType().getSimpleName().toLowerCase();
450477
}
451-
dbo.put("$ref", collection);
452478

453-
String db = dbref.db();
454-
if (!"".equals(db)) {
455-
dbo.put("$db", db);
479+
String dbname = dbref.db();
480+
if ("".equals(dbname)) {
481+
dbname = defaultDatabase;
456482
}
457483

458-
return dbo;
484+
DB db = mongo.getDB(dbname);
485+
return new DBRef(db, collection, id);
459486
}
460487

461488
@SuppressWarnings({"unchecked"})
@@ -510,13 +537,9 @@ protected Object getValueInternal(PersistentProperty prop, DBObject dbo, Standar
510537

511538
// It's a complex object, have to read it in
512539
if (dbo.containsField("_class")) {
513-
try {
514-
Class<?> clazz = Class.forName(dbo.get("_class").toString());
515-
dbo.removeField("_class");
516-
o = read(clazz, (DBObject) dbObj);
517-
} catch (ClassNotFoundException e) {
518-
throw new MappingException(e.getMessage(), e);
519-
}
540+
Class<?> toType = findTypeToBeUsed((DBObject) dbObj);
541+
dbo.removeField("_class");
542+
o = read(toType, (DBObject) dbObj);
520543
} else {
521544
o = read(mappingContext.getPersistentEntity(prop.getTypeInformation()), (DBObject) dbObj);
522545
}

spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/Address.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
package org.springframework.data.document.mongodb.mapping;
1818

19-
import java.io.Serializable;
20-
2119
/**
2220
* @author Jon Brisbin <jbrisbin@vmware.com>
2321
*/
24-
public class Address implements Serializable {
22+
public class Address {
2523

2624
private String[] lines;
2725
private String city;

spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GenericMappingTests.java

+16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright (c) 2011 by the original author(s).
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package org.springframework.data.document.mongodb.mapping;
218

319
import static org.hamcrest.CoreMatchers.is;

spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java

+7
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,13 @@ public void testWriteEntity() {
134134
p.setAccounts(accounts);
135135
template.insert("person", p);
136136

137+
Account newAcct = new Account();
138+
newAcct.setBalance(10000.00f);
139+
template.insert("account", newAcct);
140+
141+
accounts.add(newAcct);
142+
template.save("person", p);
143+
137144
assertNotNull(p.getId());
138145
}
139146

0 commit comments

Comments
 (0)