Merge remote branch 'origin/master'

This commit is contained in:
Mark Pollack
2011-04-08 17:50:51 -04:00
8 changed files with 266 additions and 54 deletions

View File

@@ -23,6 +23,7 @@ import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -704,6 +705,18 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
return null;
}
//TODO: Need to move this to more central place
if (dbDoc.containsField("_id")) {
if (dbDoc.get("_id") instanceof String) {
ObjectId oid = convertIdValue(this.mongoConverter, dbDoc.get("_id"));
if (oid != null) {
dbDoc.put("_id", oid);
}
}
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("insert DBObject: " + dbDoc);
}
return execute(collectionName, new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
if (writeConcern == null) {
@@ -722,6 +735,17 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
return Collections.emptyList();
}
//TODO: Need to move this to more central place
for (DBObject dbDoc : dbDocList) {
if (dbDoc.containsField("_id")) {
if (dbDoc.get("_id") instanceof String) {
ObjectId oid = convertIdValue(this.mongoConverter, dbDoc.get("_id"));
if (oid != null) {
dbDoc.put("_id", oid);
}
}
}
}
execute(collectionName, new CollectionCallback<Void>() {
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
if (writeConcern == null) {
@@ -752,6 +776,18 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
return null;
}
//TODO: Need to move this to more central place
if (dbDoc.containsField("_id")) {
if (dbDoc.get("_id") instanceof String) {
ObjectId oid = convertIdValue(this.mongoConverter, dbDoc.get("_id"));
if (oid != null) {
dbDoc.put("_id", oid);
}
}
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("save DBObject: " + dbDoc);
}
return execute(collectionName, new CollectionCallback<Object>() {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
if (writeConcern == null) {
@@ -1134,32 +1170,71 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica
// no ids in this query
return;
}
final MongoPropertyDescriptor descriptor;
MongoPropertyDescriptor descriptor;
try {
descriptor = new MongoPropertyDescriptor(new PropertyDescriptor(idKey, targetClass), targetClass);
MongoPropertyDescriptor mpd = new MongoPropertyDescriptor(new PropertyDescriptor(idKey, targetClass), targetClass);
descriptor = mpd;
} catch (IntrospectionException e) {
// no property descriptor for this key
return;
// no property descriptor for this key - try the other
try {
String theOtherIdKey = "id".equals(idKey) ? "_id" : "id";
MongoPropertyDescriptor mpd2 = new MongoPropertyDescriptor(new PropertyDescriptor(theOtherIdKey, targetClass), targetClass);
descriptor = mpd2;
} catch (IntrospectionException e2) {
// no property descriptor for this key either - bail
return;
}
}
if (descriptor.isIdProperty() && descriptor.isOfIdType()) {
Object value = query.get(idKey);
ObjectId newValue = null;
try {
if (value instanceof String && ObjectId.isValid((String) value)) {
newValue = converter.convertObjectId(value);
if (value instanceof DBObject) {
DBObject dbo = (DBObject) value;
if (dbo.containsField("$in")) {
List<Object> ids = new ArrayList<Object>();
int count = 0;
for (Object o : (Object[])dbo.get("$in")) {
count++;
ObjectId newValue = convertIdValue(converter, o);
if (newValue != null) {
ids.add(newValue);
}
}
if (ids.size() > 0 && ids.size() != count) {
throw new InvalidDataAccessApiUsageException("Inconsistent set of id values provided " +
Arrays.asList((Object[])dbo.get("$in")));
}
if (ids.size() > 0) {
dbo.removeField("$in");
dbo.put("$in", ids.toArray());
}
}
} catch (ConversionFailedException iae) {
LOGGER.warn("Unable to convert the String " + value + " to an ObjectId");
}
query.removeField(idKey);
if (newValue != null) {
query.put(MongoPropertyDescriptor.ID_KEY, newValue);
} else {
query.removeField(idKey);
query.put(MongoPropertyDescriptor.ID_KEY, value);
}
else {
ObjectId newValue = convertIdValue(converter, value);
query.removeField(idKey);
if (newValue != null) {
query.put(MongoPropertyDescriptor.ID_KEY, newValue);
} else {
query.put(MongoPropertyDescriptor.ID_KEY, value);
}
}
}
}
private ObjectId convertIdValue(MongoConverter converter, Object value) {
ObjectId newValue = null;
try {
if (value instanceof String && ObjectId.isValid((String) value)) {
newValue = converter.convertObjectId(value);
}
} catch (ConversionFailedException iae) {
LOGGER.warn("Unable to convert the String " + value + " to an ObjectId");
}
return newValue;
}
/**
* Substitutes the id key if it is found in he query. Any 'id' keys will be replaced with '_id'. No conversion
* of the value to an ObjectId is possible since we don't have access to a targetClass or a converter. This

View File

@@ -27,8 +27,10 @@ import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
@@ -89,28 +91,28 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
/**
* Creates a new {@link MappingMongoConverter} with the given {@link MappingContext}.
*
*
* @param mappingContext
*/
public MappingMongoConverter(MappingContext mappingContext) {
this.mappingContext = mappingContext;
this.conversionService.removeConvertible(Object.class, String.class);
}
/**
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over
* metadata driven conversion between of objects to/from DBObject
*
* @param converters
*/
public void setConverters(List<Converter<?, ?>> converters) {
if (null != converters) {
for (Converter<?, ?> c : converters) {
registerConverter(c);
conversionService.addConverter(c);
}
}
}
/**
* Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over
* metadata driven conversion between of objects to/from DBObject
*
* @param converters
*/
public void setConverters(List<Converter<?, ?>> converters) {
if (null != converters) {
for (Converter<?, ?> c : converters) {
registerConverter(c);
conversionService.addConverter(c);
}
}
}
/**
* Inspects the given {@link Converter} for the types it can convert and registers the pair for custom type conversion
@@ -379,17 +381,17 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
private void initializeConverters() {
if (!conversionService.canConvert(ObjectId.class, String.class)) {
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
}
if (!conversionService.canConvert(String.class, ObjectId.class)) {
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
}
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
}
if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) {
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
}
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
}
if (!conversionService.canConvert(String.class, ObjectId.class)) {
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
}
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
}
if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) {
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
}
MappingBeanHelper.setConversionService(conversionService);
}
@@ -405,7 +407,10 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
BasicDBList dbList = new BasicDBList();
Collection<?> coll;
if (type.isArray()) {
coll = Arrays.asList((Object[]) obj);
coll = new ArrayList<Object>();
for (Object o : (Object[]) obj) {
((List) coll).add(o);
}
} else {
coll = (Collection<?>) obj;
}
@@ -562,7 +567,11 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
items[i] = dbObjItem;
}
}
return Arrays.asList(items);
List<Object> itemsToReturn = new LinkedList<Object>();
for (Object obj : items) {
itemsToReturn.add(obj);
}
return itemsToReturn;
}
Class<?> toType = findTypeToBeUsed((DBObject) dbObj);
@@ -602,7 +611,7 @@ public class MappingMongoConverter implements MongoConverter, ApplicationContext
}
public void afterPropertiesSet() {
initializeConverters();
initializeConverters();
}
protected class PersistentPropertyWrapper {

View File

@@ -29,18 +29,18 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
public @interface CompoundIndex {
String def();
String def();
IndexDirection direction() default IndexDirection.ASCENDING;
IndexDirection direction() default IndexDirection.ASCENDING;
boolean unique() default false;
boolean unique() default false;
boolean sparse() default false;
boolean sparse() default false;
boolean dropDups() default true;
boolean dropDups() default false;
String name() default "";
String name() default "";
String collection() default "";
String collection() default "";
}

View File

@@ -35,7 +35,7 @@ public @interface Indexed {
boolean sparse() default false;
boolean dropDups() default true;
boolean dropDups() default false;
String name() default "";

View File

@@ -137,7 +137,7 @@ public class SimpleMongoRepository<T, ID extends Serializable> implements Paging
*/
public void delete(T entity) {
template.remove(entityInformation.getCollectionName(), getIdQuery(entityInformation.getId(entity)));
template.remove(entityInformation.getCollectionName(), getIdQuery(entityInformation.getId(entity)), entity.getClass());
}
/*

View File

@@ -0,0 +1,44 @@
/*
* 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.springframework.data.annotation.Id;
import org.springframework.data.document.mongodb.index.Indexed;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Document(collection = "foobar")
public class CustomCollectionWithIndex {
@Id
private String id;
@Indexed
private String name;
public CustomCollectionWithIndex(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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.springframework.data.annotation.Id;
import org.springframework.data.document.mongodb.index.Indexed;
/**
* @author Jon Brisbin <jbrisbin@vmware.com>
*/
@Document
public class DetectedCollectionWithIndex {
@Id
private String id;
@Indexed
private String name;
public DetectedCollectionWithIndex(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -25,13 +25,18 @@ import java.util.List;
import java.util.Map;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.data.document.mongodb.CollectionCallback;
import org.springframework.data.document.mongodb.MongoDbUtils;
import org.springframework.data.document.mongodb.MongoTemplate;
import org.springframework.data.document.mongodb.query.Criteria;
@@ -44,6 +49,7 @@ public class MappingTests {
private static final Log LOGGER = LogFactory.getLog(MongoDbUtils.class);
private final String[] collectionsToDrop = new String[]{
"foobar",
"person",
"personmapproperty",
"personpojo",
@@ -223,4 +229,37 @@ public class MappingTests {
assertThat(result.size(), is(1));
}
@Test
public void testIndexesCreatedInRightCollection() {
CustomCollectionWithIndex ccwi = new CustomCollectionWithIndex("test");
template.insert(ccwi);
assertTrue(template.execute("foobar", new CollectionCallback<Boolean>() {
public Boolean doInCollection(DBCollection collection) throws MongoException, DataAccessException {
List<DBObject> indexes = collection.getIndexInfo();
for (DBObject dbo : indexes) {
if ("name_1".equals(dbo.get("name"))) {
return true;
}
}
return false;
}
}));
DetectedCollectionWithIndex dcwi = new DetectedCollectionWithIndex("test");
template.insert(dcwi);
assertTrue(template.execute(DetectedCollectionWithIndex.class.getSimpleName().toLowerCase(), new CollectionCallback<Boolean>() {
public Boolean doInCollection(DBCollection collection) throws MongoException, DataAccessException {
List<DBObject> indexes = collection.getIndexInfo();
for (DBObject dbo : indexes) {
if ("name_1".equals(dbo.get("name"))) {
return true;
}
}
return false;
}
}));
}
}