DATADOC-4 - Improved MongoTemplate exception handling
- moved exception translation from MongoDbUtils to MongoExceptionTranslator - don't let MongoFactoryBean implement PersistenceExceptionTranslator - heavily refactored MongoTemplate to let higher level methods use callbacks to centralize exception handling in the callback executing methods - changed return type of MongoOperations.getCollectionNames to Set<String> as returning a List implies same order, that we can't guarantee actually - polished JavaDoc of MongoOperations - added assertions to methods - changed methods taking a List<Object> to take a List<? extends Object> instead - added abstract unit test for MongoOperations to define tests regarding expected exception behavior - let MongoTemplateUnitTests extend MongoOperationsUnitTests
This commit is contained in:
@@ -18,18 +18,11 @@ package org.springframework.data.document.mongodb;
|
|||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.dao.DataAccessResourceFailureException;
|
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
|
||||||
import org.springframework.data.document.UncategorizedDocumentStoreException;
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
import com.mongodb.DB;
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
import com.mongodb.MongoException;
|
|
||||||
import com.mongodb.MongoException.DuplicateKey;
|
|
||||||
import com.mongodb.MongoException.Network;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class featuring helper methods for internal MongoDb classes.
|
* Helper class featuring helper methods for internal MongoDb classes.
|
||||||
@@ -52,36 +45,6 @@ abstract class MongoDbUtils {
|
|||||||
private MongoDbUtils() {
|
private MongoDbUtils() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the given runtime exception to an appropriate exception from the
|
|
||||||
* <code>org.springframework.dao</code> hierarchy.
|
|
||||||
* Return null if no translation is appropriate: any other exception may
|
|
||||||
* have resulted from user code, and should not be translated.
|
|
||||||
* @param ex runtime exception that occurred
|
|
||||||
* @return the corresponding DataAccessException instance,
|
|
||||||
* or <code>null</code> if the exception should not be translated
|
|
||||||
*/
|
|
||||||
public static DataAccessException translateMongoExceptionIfPossible(RuntimeException ex) {
|
|
||||||
|
|
||||||
// Check for well-known MongoException subclasses.
|
|
||||||
|
|
||||||
// All other MongoExceptions
|
|
||||||
if(ex instanceof DuplicateKey) {
|
|
||||||
return new DataIntegrityViolationException(ex.getMessage(),ex);
|
|
||||||
}
|
|
||||||
if(ex instanceof Network) {
|
|
||||||
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
if (ex instanceof MongoException) {
|
|
||||||
return new UncategorizedDocumentStoreException(ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we get here, we have an exception that resulted from user code,
|
|
||||||
// rather than the persistence provider, so we return null to indicate
|
|
||||||
// that translation should not occur.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
|
||||||
|
|||||||
@@ -16,24 +16,51 @@
|
|||||||
package org.springframework.data.document.mongodb;
|
package org.springframework.data.document.mongodb;
|
||||||
|
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||||
|
import org.springframework.data.document.UncategorizedDocumentStoreException;
|
||||||
|
|
||||||
|
import com.mongodb.MongoException;
|
||||||
|
import com.mongodb.MongoException.DuplicateKey;
|
||||||
|
import com.mongodb.MongoException.Network;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple {@link PersistenceExceptionTranslator} for Mongo.
|
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
|
||||||
|
* exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is
|
||||||
|
* appropriate: any other exception may have resulted from user code, and should not be translated.
|
||||||
|
* @param ex runtime exception that occurred
|
||||||
|
* @return the corresponding DataAccessException instance, or {@literal null} if the exception should not be translated
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
|
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
* @see org.springframework.dao.support.PersistenceExceptionTranslator#
|
||||||
* translateExceptionIfPossible(java.lang.RuntimeException)
|
* translateExceptionIfPossible(java.lang.RuntimeException)
|
||||||
*/
|
*/
|
||||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||||
|
|
||||||
return MongoDbUtils.translateMongoExceptionIfPossible(ex);
|
// Check for well-known MongoException subclasses.
|
||||||
}
|
|
||||||
|
// All other MongoExceptions
|
||||||
|
if (ex instanceof DuplicateKey) {
|
||||||
|
return new DataIntegrityViolationException(ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
if (ex instanceof Network) {
|
||||||
|
return new DataAccessResourceFailureException(ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
if (ex instanceof MongoException) {
|
||||||
|
return new UncategorizedDocumentStoreException(ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here, we have an exception that resulted from user code,
|
||||||
|
// rather than the persistence provider, so we return null to indicate
|
||||||
|
// that translation should not occur.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.dao.DataAccessException;
|
|
||||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
@@ -38,8 +36,7 @@ import com.mongodb.ServerAddress;
|
|||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean,
|
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean {
|
||||||
PersistenceExceptionTranslator {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,10 +117,4 @@ public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
|
||||||
logger.debug("Translating " + ex);
|
|
||||||
return MongoDbUtils.translateMongoExceptionIfPossible(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
package org.springframework.data.document.mongodb;
|
package org.springframework.data.document.mongodb;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
@@ -27,7 +28,7 @@ import com.mongodb.DBObject;
|
|||||||
*
|
*
|
||||||
* @author Thomas Risberg
|
* @author Thomas Risberg
|
||||||
* @author Mark Pollack
|
* @author Mark Pollack
|
||||||
*
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public interface MongoOperations {
|
public interface MongoOperations {
|
||||||
|
|
||||||
@@ -38,7 +39,7 @@ public interface MongoOperations {
|
|||||||
String getDefaultCollectionName();
|
String getDefaultCollectionName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default collection used by this template
|
* The default collection used by this template.
|
||||||
* @return The default collection used by this template
|
* @return The default collection used by this template
|
||||||
*/
|
*/
|
||||||
DBCollection getDefaultCollection();
|
DBCollection getDefaultCollection();
|
||||||
@@ -117,17 +118,17 @@ public interface MongoOperations {
|
|||||||
DBCollection createCollection(String collectionName);
|
DBCollection createCollection(String collectionName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a collect with the provided name and options
|
* Create a collect with the provided name and options.
|
||||||
* @param collectionName name of the collection
|
* @param collectionName name of the collection
|
||||||
* @param collectionOptions options to use when creating the collection.
|
* @param collectionOptions options to use when creating the collection.
|
||||||
*/
|
*/
|
||||||
void createCollection(String collectionName, CollectionOptions collectionOptions);
|
void createCollection(String collectionName, CollectionOptions collectionOptions);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of collection names
|
* A set of collection names.
|
||||||
* @return list of collection names
|
* @return list of collection names
|
||||||
*/
|
*/
|
||||||
List<String> getCollectionNames();
|
Set<String> getCollectionNames();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a collection by name, creating it if it doesn't exist.
|
* Get a collection by name, creating it if it doesn't exist.
|
||||||
@@ -216,14 +217,14 @@ public interface MongoOperations {
|
|||||||
*
|
*
|
||||||
* @param listToSave the list of objects to save.
|
* @param listToSave the list of objects to save.
|
||||||
*/
|
*/
|
||||||
void insertList(List<Object> listToSave);
|
void insertList(List<? extends Object> listToSave);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a list of objects into the specified collection in a single batch write to the database.
|
* Insert a list of objects into the specified collection in a single batch write to the database.
|
||||||
* @param collectionName name of the collection to store the object in
|
* @param collectionName name of the collection to store the object in
|
||||||
* @param listToSave the list of objects to save.
|
* @param listToSave the list of objects to save.
|
||||||
*/
|
*/
|
||||||
void insertList(String collectionName, List<Object> listToSave);
|
void insertList(String collectionName, List<? extends Object> listToSave);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a list of objects into the specified collection using the provided MongoWriter instance
|
* Insert a list of objects into the specified collection using the provided MongoWriter instance
|
||||||
@@ -233,7 +234,7 @@ public interface MongoOperations {
|
|||||||
* @param listToSave the list of objects to save.
|
* @param listToSave the list of objects to save.
|
||||||
* @param writer the writer to convert the object to save into a DBObject
|
* @param writer the writer to convert the object to save into a DBObject
|
||||||
*/
|
*/
|
||||||
<T> void insertList(String collectionName, List<T> listToSave, MongoWriter<T> writer);
|
<T> void insertList(String collectionName, List<? extends T> listToSave, MongoWriter<T> writer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the object to the default collection. This will perform an insert if the object is not already
|
* Save the object to the default collection. This will perform an insert if the object is not already
|
||||||
|
|||||||
@@ -16,19 +16,20 @@
|
|||||||
|
|
||||||
package org.springframework.data.document.mongodb;
|
package org.springframework.data.document.mongodb;
|
||||||
|
|
||||||
import static java.lang.String.*;
|
|
||||||
|
|
||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.BeanWrapper;
|
import org.springframework.beans.BeanWrapper;
|
||||||
import org.springframework.beans.PropertyAccessorFactory;
|
import org.springframework.beans.PropertyAccessorFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.dao.DataRetrievalFailureException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
|
import org.springframework.jca.cci.core.ConnectionCallback;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
@@ -39,7 +40,6 @@ import com.mongodb.DBCursor;
|
|||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
import com.mongodb.Mongo;
|
import com.mongodb.Mongo;
|
||||||
import com.mongodb.MongoException;
|
import com.mongodb.MongoException;
|
||||||
import com.mongodb.WriteResult;
|
|
||||||
import com.mongodb.util.JSON;
|
import com.mongodb.util.JSON;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,10 +53,10 @@ import com.mongodb.util.JSON;
|
|||||||
public class MongoTemplate implements InitializingBean, MongoOperations {
|
public class MongoTemplate implements InitializingBean, MongoOperations {
|
||||||
|
|
||||||
private static final String ID = "_id";
|
private static final String ID = "_id";
|
||||||
private static final String COLLECTION_ERROR_TEMPLATE = "Error creating collection %s: %s";
|
|
||||||
|
|
||||||
private final MongoConverter mongoConverter;
|
private final MongoConverter mongoConverter;
|
||||||
private final Mongo mongo;
|
private final Mongo mongo;
|
||||||
|
private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
|
||||||
|
|
||||||
private String defaultCollectionName;
|
private String defaultCollectionName;
|
||||||
private String databaseName;
|
private String databaseName;
|
||||||
@@ -98,7 +98,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the password to use to authenticate with the Mongo database
|
* Sets the password to use to authenticate with the Mongo database.
|
||||||
*
|
*
|
||||||
* @param password The password to use
|
* @param password The password to use
|
||||||
*/
|
*/
|
||||||
@@ -107,10 +107,20 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the default collection to be used.
|
||||||
|
*
|
||||||
|
* @param defaultCollectionName
|
||||||
|
*/
|
||||||
public void setDefaultCollectionName(String defaultCollectionName) {
|
public void setDefaultCollectionName(String defaultCollectionName) {
|
||||||
this.defaultCollectionName = defaultCollectionName;
|
this.defaultCollectionName = defaultCollectionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the database name to be used.
|
||||||
|
*
|
||||||
|
* @param databaseName
|
||||||
|
*/
|
||||||
public void setDatabaseName(String databaseName) {
|
public void setDatabaseName(String databaseName) {
|
||||||
Assert.notNull(databaseName);
|
Assert.notNull(databaseName);
|
||||||
this.databaseName = databaseName;
|
this.databaseName = databaseName;
|
||||||
@@ -127,7 +137,12 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
* @see org.springframework.data.document.mongodb.MongoOperations#getDefaultCollection()
|
* @see org.springframework.data.document.mongodb.MongoOperations#getDefaultCollection()
|
||||||
*/
|
*/
|
||||||
public DBCollection getDefaultCollection() {
|
public DBCollection getDefaultCollection() {
|
||||||
return getDb().getCollection(getDefaultCollectionName());
|
|
||||||
|
return execute(new DBCallback<DBCollection>() {
|
||||||
|
public DBCollection doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
|
return db.getCollection(getDefaultCollectionName());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -140,33 +155,41 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#executeCommand(com.mongodb.DBObject)
|
* @see org.springframework.data.document.mongodb.MongoOperations#executeCommand(com.mongodb.DBObject)
|
||||||
*/
|
*/
|
||||||
public void executeCommand(DBObject command) {
|
public void executeCommand(final DBObject command) {
|
||||||
CommandResult cr = getDb().command(command);
|
|
||||||
String err = cr.getErrorMessage();
|
CommandResult result = execute(new DBCallback<CommandResult>() {
|
||||||
if (err != null) {
|
public CommandResult doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
throw new InvalidDataAccessApiUsageException("Command execution of " +
|
return db.command(command);
|
||||||
command.toString() + " failed: " + err);
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
String error = result.getErrorMessage();
|
||||||
|
if (error != null) {
|
||||||
|
throw new InvalidDataAccessApiUsageException("Command execution of " +
|
||||||
|
command.toString() + " failed: " + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#execute(org.springframework.data.document.mongodb.DBCallback)
|
* @see org.springframework.data.document.mongodb.MongoOperations#execute(org.springframework.data.document.mongodb.DBCallback)
|
||||||
*/
|
*/
|
||||||
public <T> T execute(DBCallback<T> action) {
|
public <T> T execute(DbCallback<T> action) {
|
||||||
DB db = getDb();
|
|
||||||
|
Assert.notNull(action);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
DB db = getDb();
|
||||||
return action.doInDB(db);
|
return action.doInDB(db);
|
||||||
} catch (MongoException e) {
|
} catch (MongoException e) {
|
||||||
throw MongoDbUtils.translateMongoExceptionIfPossible(e);
|
throw potentiallyConvertRuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#execute(org.springframework.data.document.mongodb.CollectionCallback)
|
* @see org.springframework.data.document.mongodb.MongoOperations#execute(org.springframework.data.document.mongodb.CollectionCallback)
|
||||||
*/
|
*/
|
||||||
public <T> T execute(CollectionCallback<T> action) {
|
public <T> T execute(CollectionCallback<T> callback) {
|
||||||
return execute(action, defaultCollectionName);
|
return execute(callback, defaultCollectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -174,79 +197,126 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
*/
|
*/
|
||||||
public <T> T execute(CollectionCallback<T> callback, String collectionName) {
|
public <T> T execute(CollectionCallback<T> callback, String collectionName) {
|
||||||
|
|
||||||
|
Assert.notNull(callback);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return callback.doInCollection(getCollection(collectionName));
|
DBCollection collection = getDb().getCollection(collectionName);
|
||||||
|
return callback.doInCollection(collection);
|
||||||
} catch (MongoException e) {
|
} catch (MongoException e) {
|
||||||
throw MongoDbUtils.translateMongoExceptionIfPossible(e);
|
throw potentiallyConvertRuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Central callback executing method to do queries against the datastore that requires reading a collection of
|
||||||
|
* objects. It will take the following steps <ol> <li>Execute the given {@link ConnectionCallback} for a
|
||||||
|
* {@link DBCursor}.</li> <li>Prepare that {@link DBCursor} with the given {@link CursorPreparer} (will be skipped
|
||||||
|
* if {@link CursorPreparer} is {@literal null}</li> <li>Iterate over the {@link DBCursor} and applies the given
|
||||||
|
* {@link DbObjectCallback} to each of the {@link DBObject}s collecting the actual result {@link List}.</li> <ol>
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* @param collectionCallback the callback to retrieve the {@link DBCursor} with
|
||||||
|
* @param preparer the {@link CursorPreparer} to potentially modify the {@link DBCursor} before ireating over it
|
||||||
|
* @param objectCallback the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type
|
||||||
|
* @param collectionName the collection to be queried
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private <T> List<T> executeEach(CollectionCallback<DBCursor> collectionCallback, CursorPreparer preparer,
|
||||||
|
DbObjectCallback<T> objectCallback, String collectionName) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
DBCursor cursor = collectionCallback.doInCollection(getCollection(collectionName));
|
||||||
|
|
||||||
|
if (preparer != null) {
|
||||||
|
preparer.prepare(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<T> result = new ArrayList<T>();
|
||||||
|
|
||||||
|
for (DBObject object : cursor) {
|
||||||
|
result.add(objectCallback.doWith(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (MongoException e) {
|
||||||
|
throw potentiallyConvertRuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#executeInSession(org.springframework.data.document.mongodb.DBCallback)
|
* @see org.springframework.data.document.mongodb.MongoOperations#executeInSession(org.springframework.data.document.mongodb.DBCallback)
|
||||||
*/
|
*/
|
||||||
public <T> T executeInSession(DBCallback<T> action) {
|
public <T> T executeInSession(final DBCallback<T> action) {
|
||||||
DB db = getDb();
|
|
||||||
db.requestStart();
|
return execute(new DBCallback<T>() {
|
||||||
try {
|
public T doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
return action.doInDB(db);
|
try {
|
||||||
} catch (MongoException e) {
|
db.requestStart();
|
||||||
throw MongoDbUtils.translateMongoExceptionIfPossible(e);
|
return action.doInDB(db);
|
||||||
} finally {
|
} finally {
|
||||||
db.requestDone();
|
db.requestDone();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#createCollection(java.lang.String)
|
* @see org.springframework.data.document.mongodb.MongoOperations#createCollection(java.lang.String)
|
||||||
*/
|
*/
|
||||||
public DBCollection createCollection(String collectionName) {
|
public DBCollection createCollection(final String collectionName) {
|
||||||
try {
|
return execute(new DBCallback<DBCollection>() {
|
||||||
return getDb().createCollection(collectionName, new BasicDBObject());
|
public DBCollection doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
} catch (MongoException e) {
|
return db.createCollection(collectionName, new BasicDBObject());
|
||||||
throw new InvalidDataAccessApiUsageException(format(COLLECTION_ERROR_TEMPLATE, collectionName, e.getMessage()), e);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#createCollection(java.lang.String, org.springframework.data.document.mongodb.CollectionOptions)
|
* @see org.springframework.data.document.mongodb.MongoOperations#createCollection(java.lang.String, org.springframework.data.document.mongodb.CollectionOptions)
|
||||||
*/
|
*/
|
||||||
public void createCollection(String collectionName, CollectionOptions collectionOptions) {
|
public void createCollection(final String collectionName, final CollectionOptions collectionOptions) {
|
||||||
try {
|
execute(new DBCallback<Void>() {
|
||||||
getDb().createCollection(collectionName, convertToDbObject(collectionOptions));
|
public Void doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
} catch (MongoException e) {
|
db.createCollection(collectionName, convertToDbObject(collectionOptions));
|
||||||
throw new InvalidDataAccessApiUsageException(format(COLLECTION_ERROR_TEMPLATE, collectionName, e.getMessage()), e);
|
return null;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.String)
|
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.String)
|
||||||
*/
|
*/
|
||||||
public DBCollection getCollection(String collectionName) {
|
public DBCollection getCollection(final String collectionName) {
|
||||||
try {
|
return execute(new DBCallback<DBCollection>() {
|
||||||
return getDb().getCollection(collectionName);
|
public DBCollection doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
} catch (MongoException e) {
|
return db.getCollection(collectionName);
|
||||||
throw new InvalidDataAccessApiUsageException(format(COLLECTION_ERROR_TEMPLATE, collectionName, e.getMessage()), e);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#collectionExists(java.lang.String)
|
* @see org.springframework.data.document.mongodb.MongoOperations#collectionExists(java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean collectionExists(String collectionName) {
|
public boolean collectionExists(final String collectionName) {
|
||||||
try {
|
return execute(new DBCallback<Boolean>() {
|
||||||
return getDb().collectionExists(collectionName);
|
public Boolean doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
} catch (MongoException e) {
|
return db.collectionExists(collectionName);
|
||||||
throw new InvalidDataAccessApiUsageException("Error creating collection " + collectionName + ": " + e.getMessage(), e);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#dropCollection(java.lang.String)
|
* @see org.springframework.data.document.mongodb.MongoOperations#dropCollection(java.lang.String)
|
||||||
*/
|
*/
|
||||||
public void dropCollection(String collectionName) {
|
public void dropCollection(String collectionName) {
|
||||||
getDb().getCollection(collectionName)
|
|
||||||
.drop();
|
execute(new CollectionCallback<Void>() {
|
||||||
|
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
|
collection.drop();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, collectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -287,21 +357,24 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#insertList(java.util.List)
|
* @see org.springframework.data.document.mongodb.MongoOperations#insertList(java.util.List)
|
||||||
*/
|
*/
|
||||||
public void insertList(List<Object> listToSave) {
|
public void insertList(List<? extends Object> listToSave) {
|
||||||
insertList(getRequiredDefaultCollectionName(), listToSave);
|
insertList(getRequiredDefaultCollectionName(), listToSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#insertList(java.lang.String, java.util.List)
|
* @see org.springframework.data.document.mongodb.MongoOperations#insertList(java.lang.String, java.util.List)
|
||||||
*/
|
*/
|
||||||
public void insertList(String collectionName, List<Object> listToSave) {
|
public void insertList(String collectionName, List<? extends Object> listToSave) {
|
||||||
insertList(collectionName, listToSave, this.mongoConverter);
|
insertList(collectionName, listToSave, this.mongoConverter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#insertList(java.lang.String, java.util.List, org.springframework.data.document.mongodb.MongoWriter)
|
* @see org.springframework.data.document.mongodb.MongoOperations#insertList(java.lang.String, java.util.List, org.springframework.data.document.mongodb.MongoWriter)
|
||||||
*/
|
*/
|
||||||
public <T> void insertList(String collectionName, List<T> listToSave, MongoWriter<T> writer) {
|
public <T> void insertList(String collectionName, List<? extends T> listToSave, MongoWriter<T> writer) {
|
||||||
|
|
||||||
|
Assert.notNull(writer);
|
||||||
|
|
||||||
List<DBObject> dbObjectList = new ArrayList<DBObject>();
|
List<DBObject> dbObjectList = new ArrayList<DBObject>();
|
||||||
for (T o : listToSave) {
|
for (T o : listToSave) {
|
||||||
BasicDBObject dbDoc = new BasicDBObject();
|
BasicDBObject dbDoc = new BasicDBObject();
|
||||||
@@ -341,51 +414,56 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Object insertDBObject(String collectionName, DBObject dbDoc) {
|
protected Object insertDBObject(String collectionName, final DBObject dbDoc) {
|
||||||
if (dbDoc.keySet().size() > 0 ) {
|
|
||||||
WriteResult wr = null;
|
if (dbDoc.keySet().isEmpty()) {
|
||||||
try {
|
|
||||||
wr = getDb().getCollection(collectionName).insert(dbDoc);
|
|
||||||
return dbDoc.get(ID);
|
|
||||||
} catch (MongoException e) {
|
|
||||||
throw new DataRetrievalFailureException(wr.getLastError().getErrorMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return execute(new CollectionCallback<Object>() {
|
||||||
|
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
|
collection.insert(dbDoc);
|
||||||
|
return dbDoc.get(ID);
|
||||||
|
}
|
||||||
|
}, collectionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected List<Object> insertDBObjectList(String collectionName, final List<DBObject> dbDocList) {
|
||||||
|
|
||||||
|
if (dbDocList.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
execute(new CollectionCallback<Void>() {
|
||||||
|
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
|
collection.insert(dbDocList);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, collectionName);
|
||||||
|
|
||||||
|
List<Object> ids = new ArrayList<Object>();
|
||||||
|
for (DBObject dbo : dbDocList) {
|
||||||
|
ids.add(dbo.get(ID));
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Object> insertDBObjectList(String collectionName, List<DBObject> dbDocList) {
|
protected Object saveDBObject(String collectionName, final DBObject dbDoc) {
|
||||||
if (!dbDocList.isEmpty()) {
|
|
||||||
List<Object> ids = new ArrayList<Object>();
|
if (dbDoc.keySet().isEmpty()) {
|
||||||
WriteResult wr = null;
|
|
||||||
try {
|
|
||||||
wr = getDb().getCollection(collectionName).insert(dbDocList);
|
|
||||||
for (DBObject dbo : dbDocList) {
|
|
||||||
ids.add(dbo.get(ID));
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
} catch (MongoException e) {
|
|
||||||
throw new DataRetrievalFailureException(wr.getLastError().getErrorMessage(), e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return execute(new CollectionCallback<Object>() {
|
||||||
|
|
||||||
protected Object saveDBObject(String collectionName, DBObject dbDoc) {
|
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
if (dbDoc.keySet().size() > 0 ) {
|
collection.save(dbDoc);
|
||||||
WriteResult wr = null;
|
|
||||||
try {
|
|
||||||
wr = getDb().getCollection(collectionName).save(dbDoc);
|
|
||||||
return dbDoc.get(ID);
|
return dbDoc.get(ID);
|
||||||
} catch (MongoException e) {
|
|
||||||
throw new DataRetrievalFailureException(wr.getLastError().getErrorMessage(), e);
|
|
||||||
}
|
}
|
||||||
} else {
|
}, collectionName);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -398,13 +476,13 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#updateFirst(java.lang.String, com.mongodb.DBObject, com.mongodb.DBObject)
|
* @see org.springframework.data.document.mongodb.MongoOperations#updateFirst(java.lang.String, com.mongodb.DBObject, com.mongodb.DBObject)
|
||||||
*/
|
*/
|
||||||
public void updateFirst(String collectionName, DBObject queryDoc, DBObject updateDoc) {
|
public void updateFirst(String collectionName, final DBObject queryDoc, final DBObject updateDoc) {
|
||||||
|
execute(new CollectionCallback<Void>() {
|
||||||
try {
|
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
getDb().getCollection(collectionName).update(queryDoc, updateDoc);
|
collection.update(queryDoc, updateDoc);
|
||||||
} catch (MongoException e) {
|
return null;
|
||||||
throw new DataRetrievalFailureException("Error during update using " + queryDoc + ", " + updateDoc + "!", e);
|
}
|
||||||
}
|
}, collectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -417,12 +495,13 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#updateMulti(java.lang.String, com.mongodb.DBObject, com.mongodb.DBObject)
|
* @see org.springframework.data.document.mongodb.MongoOperations#updateMulti(java.lang.String, com.mongodb.DBObject, com.mongodb.DBObject)
|
||||||
*/
|
*/
|
||||||
public void updateMulti(String collectionName, DBObject queryDoc, DBObject updateDoc) {
|
public void updateMulti(String collectionName, final DBObject queryDoc, final DBObject updateDoc) {
|
||||||
try {
|
execute(new CollectionCallback<Void>() {
|
||||||
getDb().getCollection(collectionName).updateMulti(queryDoc, updateDoc);
|
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
} catch (MongoException e) {
|
collection.updateMulti(queryDoc, updateDoc);
|
||||||
throw new DataRetrievalFailureException("Error during updateMulti using " + queryDoc + ", " + updateDoc + "!", e);
|
return null;
|
||||||
}
|
}
|
||||||
|
}, collectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -435,12 +514,13 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#remove(java.lang.String, com.mongodb.DBObject)
|
* @see org.springframework.data.document.mongodb.MongoOperations#remove(java.lang.String, com.mongodb.DBObject)
|
||||||
*/
|
*/
|
||||||
public void remove(String collectionName, DBObject queryDoc) {
|
public void remove(String collectionName, final DBObject queryDoc) {
|
||||||
try {
|
execute(new CollectionCallback<Void>() {
|
||||||
getDb().getCollection(collectionName).remove(queryDoc);
|
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
} catch (MongoException e) {
|
collection.remove(queryDoc);
|
||||||
throw new DataRetrievalFailureException("Error during remove using " + queryDoc + "!", e);
|
return null;
|
||||||
}
|
}
|
||||||
|
}, collectionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -448,53 +528,35 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.Class)
|
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.Class)
|
||||||
*/
|
*/
|
||||||
public <T> List<T> getCollection(Class<T> targetClass) {
|
public <T> List<T> getCollection(Class<T> targetClass) {
|
||||||
|
return executeEach(new FindCallback(null), null, new ReadDbObjectCallback<T>(mongoConverter, targetClass),
|
||||||
List<T> results = new ArrayList<T>();
|
getDefaultCollectionName());
|
||||||
DBCollection collection = getDb().getCollection(getDefaultCollectionName());
|
|
||||||
for (DBObject dbo : collection.find()) {
|
|
||||||
Object obj = mongoConverter.read(targetClass, dbo);
|
|
||||||
//effectively acts as a query on the collection restricting it to elements of a specific type
|
|
||||||
if (targetClass.isInstance(obj)) {
|
|
||||||
results.add(targetClass.cast(obj));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.String, java.lang.Class)
|
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.String, java.lang.Class)
|
||||||
*/
|
*/
|
||||||
public <T> List<T> getCollection(String collectionName, Class<T> targetClass) {
|
public <T> List<T> getCollection(String collectionName, Class<T> targetClass) {
|
||||||
|
return executeEach(new FindCallback(null), null, new ReadDbObjectCallback<T>(mongoConverter, targetClass),
|
||||||
List<T> results = new ArrayList<T>();
|
collectionName);
|
||||||
DBCollection collection = getDb().getCollection(collectionName);
|
|
||||||
for (DBObject dbo : collection.find()) {
|
|
||||||
Object obj = mongoConverter.read(targetClass, dbo);
|
|
||||||
//effectively acts as a query on the collection restricting it to elements of a specific type
|
|
||||||
if (targetClass.isInstance(obj)) {
|
|
||||||
results.add(targetClass.cast(obj));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#getCollectionNames()
|
* @see org.springframework.data.document.mongodb.MongoOperations#getCollectionNames()
|
||||||
*/
|
*/
|
||||||
public List<String> getCollectionNames() {
|
public Set<String> getCollectionNames() {
|
||||||
return new ArrayList<String>(getDb().getCollectionNames());
|
return execute(new DBCallback<Set<String>>() {
|
||||||
|
public Set<String> doInDB(DB db) throws MongoException, DataAccessException {
|
||||||
|
return db.getCollectionNames();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.String, java.lang.Class, org.springframework.data.document.mongodb.MongoReader)
|
* @see org.springframework.data.document.mongodb.MongoOperations#getCollection(java.lang.String, java.lang.Class, org.springframework.data.document.mongodb.MongoReader)
|
||||||
*/
|
*/
|
||||||
public <T> List<T> getCollection(String collectionName, Class<T> targetClass, MongoReader<T> reader) {
|
public <T> List<T> getCollection(String collectionName, Class<T> targetClass, MongoReader<T> reader) {
|
||||||
List<T> results = new ArrayList<T>();
|
return executeEach(new FindCallback(null), null, new ReadDbObjectCallback<T>(reader, targetClass),
|
||||||
DBCollection collection = getDb().getCollection(collectionName);
|
collectionName);
|
||||||
for (DBObject dbo : collection.find()) {
|
|
||||||
results.add(reader.read(targetClass, dbo));
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queries that take JavaScript to express the query.
|
// Queries that take JavaScript to express the query.
|
||||||
@@ -504,7 +566,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
*/
|
*/
|
||||||
public <T> List<T> queryUsingJavaScript(String query, Class<T> targetClass) {
|
public <T> List<T> queryUsingJavaScript(String query, Class<T> targetClass) {
|
||||||
return query(getDefaultCollectionName(), (DBObject)JSON.parse(query), targetClass); //
|
return query(getDefaultCollectionName(), (DBObject)JSON.parse(query), targetClass); //
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#queryUsingJavaScript(java.lang.String, java.lang.Class, org.springframework.data.document.mongodb.MongoReader)
|
* @see org.springframework.data.document.mongodb.MongoOperations#queryUsingJavaScript(java.lang.String, java.lang.Class, org.springframework.data.document.mongodb.MongoReader)
|
||||||
@@ -554,7 +616,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#query(java.lang.String, com.mongodb.DBObject, java.lang.Class)
|
* @see org.springframework.data.document.mongodb.MongoOperations#query(java.lang.String, com.mongodb.DBObject, java.lang.Class)
|
||||||
*/
|
*/
|
||||||
public <T> List<T> query(String collectionName, DBObject query, Class<T> targetClass) {
|
public <T> List<T> query(String collectionName, DBObject query, Class<T> targetClass) {
|
||||||
return query(collectionName, query, targetClass, (CursorPreparer) null);
|
return query(collectionName, query, targetClass, (CursorPreparer) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,37 +624,18 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
* @see org.springframework.data.document.mongodb.MongoOperations#query(java.lang.String, com.mongodb.DBObject, java.lang.Class, org.springframework.data.document.mongodb.CursorPreparer)
|
* @see org.springframework.data.document.mongodb.MongoOperations#query(java.lang.String, com.mongodb.DBObject, java.lang.Class, org.springframework.data.document.mongodb.CursorPreparer)
|
||||||
*/
|
*/
|
||||||
public <T> List<T> query(String collectionName, DBObject query, Class<T> targetClass, CursorPreparer preparer) {
|
public <T> List<T> query(String collectionName, DBObject query, Class<T> targetClass, CursorPreparer preparer) {
|
||||||
DBCollection collection = getDb().getCollection(collectionName);
|
return executeEach(new FindCallback(query), preparer, new ReadDbObjectCallback<T>(mongoConverter, targetClass),
|
||||||
List<T> results = new ArrayList<T>();
|
collectionName);
|
||||||
DBCursor cursor = collection.find(query);
|
|
||||||
if (preparer != null) {
|
|
||||||
preparer.prepare(cursor);
|
|
||||||
}
|
|
||||||
for (DBObject dbo : cursor) {
|
|
||||||
Object obj = mongoConverter.read(targetClass,dbo);
|
|
||||||
//effectively acts as a query on the collection restricting it to elements of a specific type
|
|
||||||
if (targetClass.isInstance(obj)) {
|
|
||||||
results.add(targetClass.cast(obj));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.data.document.mongodb.MongoOperations#query(java.lang.String, com.mongodb.DBObject, java.lang.Class, org.springframework.data.document.mongodb.MongoReader)
|
* @see org.springframework.data.document.mongodb.MongoOperations#query(java.lang.String, com.mongodb.DBObject, java.lang.Class, org.springframework.data.document.mongodb.MongoReader)
|
||||||
*/
|
*/
|
||||||
public <T> List<T> query(String collectionName, DBObject query, Class<T> targetClass, MongoReader<T> reader) {
|
public <T> List<T> query(String collectionName, DBObject query, Class<T> targetClass, MongoReader<T> reader) {
|
||||||
DBCollection collection = getDb().getCollection(collectionName);
|
return executeEach(new FindCallback(query), null, new ReadDbObjectCallback<T>(reader, targetClass),
|
||||||
List<T> results = new ArrayList<T>();
|
collectionName);
|
||||||
for (DBObject dbo : collection.find(query)) {
|
|
||||||
results.add(reader.read(targetClass, dbo));
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RuntimeException convertMongoAccessException(RuntimeException ex) {
|
|
||||||
return MongoDbUtils.translateMongoExceptionIfPossible(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DB getDb() {
|
public DB getDb() {
|
||||||
return MongoDbUtils.getDB(mongo, databaseName, username, password == null ? null : password.toCharArray());
|
return MongoDbUtils.getDB(mongo, databaseName, username, password == null ? null : password.toCharArray());
|
||||||
@@ -603,7 +646,7 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
DBObject dbo = new BasicDBObject();
|
DBObject dbo = new BasicDBObject();
|
||||||
if (collectionOptions != null) {
|
if (collectionOptions != null) {
|
||||||
if (collectionOptions.getCapped() != null) {
|
if (collectionOptions.getCapped() != null) {
|
||||||
dbo.put("capped", collectionOptions.getCapped().booleanValue());
|
dbo.put("capped", collectionOptions.getCapped().booleanValue());
|
||||||
}
|
}
|
||||||
if (collectionOptions.getSize() != null) {
|
if (collectionOptions.getSize() != null) {
|
||||||
dbo.put("size", collectionOptions.getSize().intValue());
|
dbo.put("size", collectionOptions.getSize().intValue());
|
||||||
@@ -634,6 +677,19 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original
|
||||||
|
* exception if the conversation failed. Thus allows safe rethrowing of the return value.
|
||||||
|
*
|
||||||
|
* @param ex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private RuntimeException potentiallyConvertRuntimeException(RuntimeException ex) {
|
||||||
|
|
||||||
|
RuntimeException resolved = this.exceptionTranslator.translateExceptionIfPossible(ex);
|
||||||
|
return resolved == null ? ex : resolved;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
@@ -641,10 +697,62 @@ public class MongoTemplate implements InitializingBean, MongoOperations {
|
|||||||
*/
|
*/
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
if (this.getDefaultCollectionName() != null) {
|
if (this.getDefaultCollectionName() != null) {
|
||||||
DB db = getDb();
|
if (!collectionExists(getDefaultCollectionName())) {
|
||||||
if (! db.collectionExists(getDefaultCollectionName())) {
|
createCollection(getDefaultCollectionName(), null);
|
||||||
db.createCollection(getDefaultCollectionName(), null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple {@link CollectionCallback} that takes a query {@link DBObject} and executes that against the
|
||||||
|
* {@link DBCollection}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
private static class FindCallback implements CollectionCallback<DBCursor> {
|
||||||
|
|
||||||
|
private final DBObject query;
|
||||||
|
|
||||||
|
public FindCallback(DBObject query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DBCursor doInCollection(DBCollection collection) throws MongoException, DataAccessException {
|
||||||
|
return collection.find(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple internal callback to allow operations on a {@link DBObject}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
|
||||||
|
private interface DbObjectCallback<T> {
|
||||||
|
|
||||||
|
T doWith(DBObject object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple {@link DbObjectCallback} that will transform {@link DBObject} into the given target type using the given
|
||||||
|
* {@link MongoReader}.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
private static class ReadDbObjectCallback<T> implements DbObjectCallback<T> {
|
||||||
|
|
||||||
|
private final MongoReader<? super T> reader;
|
||||||
|
private final Class<T> type;
|
||||||
|
|
||||||
|
public ReadDbObjectCallback(MongoReader<? super T> reader, Class<T> type) {
|
||||||
|
this.reader = reader;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T doWith(DBObject object) {
|
||||||
|
return (T) reader.read(type, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,344 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for unit tests to specify behaviour we expect from {@link MongoOperations}. Subclasses return
|
||||||
|
* instances of their implementation and thus can see if it correctly implements the {@link MongoOperations} interface.
|
||||||
|
*
|
||||||
|
* @author Oliver Gierke
|
||||||
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public abstract class MongoOperationsUnitTests {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
CollectionCallback<Object> collectionCallback;
|
||||||
|
@Mock
|
||||||
|
DbCallback<Object> dbCallback;
|
||||||
|
|
||||||
|
MongoConverter converter;
|
||||||
|
Person person;
|
||||||
|
List<Person> persons;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public final void operationsSetUp() {
|
||||||
|
|
||||||
|
person = new Person("Oliver");
|
||||||
|
persons = Arrays.asList(person);
|
||||||
|
|
||||||
|
converter = new MongoConverter() {
|
||||||
|
|
||||||
|
public Object read(Class<? extends Object> clazz, DBObject dbo) {
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(Object t, DBObject dbo) {
|
||||||
|
dbo.put("firstName", person.getFirstName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public void rejectsNullForCollectionCallback() {
|
||||||
|
|
||||||
|
getOperations().execute((CollectionCallback) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public void rejectsNullForCollectionCallback2() {
|
||||||
|
getOperations().execute((CollectionCallback) null, "collection");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public void rejectsNullForDbCallback() {
|
||||||
|
getOperations().execute((DbCallback) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForCollectionExists() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.collectionExists("foo");
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForCreateCollection() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.createCollection("foo");
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForCreateCollection2() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.createCollection("foo", new CollectionOptions(1, 1, true));
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForDropCollection() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.dropCollection("foo");
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForExecuteCollectionCallback() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.execute(collectionCallback);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForExecuteDbCallback() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.execute(dbCallback);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForExecuteCollectionCallbackAndCollection() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.execute(collectionCallback, "collection");
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForExecuteCommand() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.executeCommand(new BasicDBObject());
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForExecuteStringCommand() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.executeCommand("");
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForExecuteInSession() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.executeInSession(dbCallback);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetCollection() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.getCollection(Object.class);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetCollectionWithCollectionName() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.getCollection("collection");
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetCollectionWithCollectionNameAndType() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.getCollection("collection", Object.class);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetCollectionWithCollectionNameTypeAndReader() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.getCollection("collection", Object.class, converter);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetCollectionNames() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.getCollectionNames();
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetDefaultCollection() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.getDefaultCollection();
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForInsert() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.insert(person);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForInsert2() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.insert("collection", person);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForInsert3() {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.insert("collection", person, converter);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForInsertList() throws Exception {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.insertList(persons);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetInsertList2() throws Exception {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.insertList("collection", persons);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertsExceptionForGetInsertList3() throws Exception {
|
||||||
|
new Execution() {
|
||||||
|
@Override
|
||||||
|
public void doWith(MongoOperations operations) {
|
||||||
|
operations.insertList("collection", persons, converter);
|
||||||
|
}
|
||||||
|
}.assertDataAccessException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract class Execution {
|
||||||
|
|
||||||
|
public void assertDataAccessException() {
|
||||||
|
assertException(DataAccessException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertException(Class<? extends Exception> exception) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
doWith(getOperationsForExceptionHandling());
|
||||||
|
fail("Expected " + exception + " but completed without any!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertTrue("Expected " + exception + " but got " + e, exception.isInstance(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void doWith(MongoOperations operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expects an {@link MongoOperations} instance that will be used to check that invoking methods on it will only
|
||||||
|
* cause {@link DataAccessException}s.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected abstract MongoOperations getOperationsForExceptionHandling();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a plain {@link MongoOperations}.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected abstract MongoOperations getOperations();
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import org.springframework.dao.DataRetrievalFailureException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
import com.mongodb.DB;
|
||||||
@@ -36,7 +36,7 @@ import com.mongodb.MongoException;
|
|||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class MongoTemplateUnitTests {
|
public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||||
|
|
||||||
MongoTemplate template;
|
MongoTemplate template;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public class MongoTemplateUnitTests {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
this.template = new MongoTemplate(mongo, "database");
|
this.template = new MongoTemplate(mongo, "database", "default");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
@@ -61,7 +61,7 @@ public class MongoTemplateUnitTests {
|
|||||||
new MongoTemplate(null, "database");
|
new MongoTemplate(null, "database");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = DataRetrievalFailureException.class)
|
@Test(expected = DataAccessException.class)
|
||||||
public void removeHandlesMongoExceptionProperly() throws Exception {
|
public void removeHandlesMongoExceptionProperly() throws Exception {
|
||||||
MongoTemplate template = mockOutGetDb();
|
MongoTemplate template = mockOutGetDb();
|
||||||
when(db.getCollection("collection")).thenThrow(new MongoException("Exception!"));
|
when(db.getCollection("collection")).thenThrow(new MongoException("Exception!"));
|
||||||
@@ -87,4 +87,22 @@ public class MongoTemplateUnitTests {
|
|||||||
stub(template.getDb()).toReturn(db);
|
stub(template.getDb()).toReturn(db);
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.document.mongodb.MongoOperationsUnitTests#getOperations()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected MongoOperations getOperationsForExceptionHandling() {
|
||||||
|
MongoTemplate template = spy(this.template);
|
||||||
|
stub(template.getDb()).toThrow(new MongoException("Error!"));
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.springframework.data.document.mongodb.MongoOperationsUnitTests#getOperations()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected MongoOperations getOperations() {
|
||||||
|
return this.template;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ public class Person {
|
|||||||
private String firstName;
|
private String firstName;
|
||||||
|
|
||||||
private Person friend;
|
private Person friend;
|
||||||
|
|
||||||
|
public Person() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(String firstname) {
|
||||||
|
this.firstName = firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getFirstName() {
|
public String getFirstName() {
|
||||||
|
|||||||
Reference in New Issue
Block a user