From 4324ed82314edfb88316a8b92e8e024e342abbcb Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 20 Jul 2011 18:46:14 +0200 Subject: [PATCH] Javadoc cleanups and a few code cleanups. --- .../core/MongoExceptionTranslator.java | 4 - .../data/mongodb/core/MongoOperations.java | 25 +- .../data/mongodb/core/MongoTemplate.java | 950 +++++------------- .../data/mongodb/core/QueryMapper.java | 2 +- .../data/mongodb/core/MongoTemplateTests.java | 18 +- .../mongodb/core/mapping/MappingTests.java | 3 +- 6 files changed, 296 insertions(+), 706 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java index 164b67129..0bff447c4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoExceptionTranslator.java @@ -23,7 +23,6 @@ import com.mongodb.MongoInternalException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; @@ -35,10 +34,7 @@ import org.springframework.data.mongodb.UncategorizedMongoDbException; * 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 * @author Oliver Gierke - * @return the corresponding DataAccessException instance, or {@literal null} if the exception should not be translated */ public class MongoExceptionTranslator implements PersistenceExceptionTranslator { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java index ad1c87d2d..1b4814120 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java @@ -24,6 +24,7 @@ import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.WriteResult; +import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.index.IndexDefinition; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; @@ -256,7 +257,7 @@ public interface MongoOperations { List findAll(Class entityClass, String collectionName); /** - * Ensure that an index for the provided {@link IndexDefinition} exists for the collection indicated by the entity class. + * Ensure that an index for the provided {@link IndexDefinition} exists for the collection indicated by the entity class. * If not it will be created. * * @param indexDefinition @@ -274,7 +275,7 @@ public interface MongoOperations { void ensureIndex(IndexDefinition indexDefinition, String collectionName); /** - * Map the results of an ad-hoc query on the collection for the entity class to a single instance of an object + * Map the results of an ad-hoc query on the collection for the entity class to a single instance of an object * of the specified type. *

* The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless @@ -397,13 +398,13 @@ public interface MongoOperations { T findById(Object id, Class entityClass, String collectionName); /** - * Map the results of an ad-hoc query on the collection for the entity type to a single instance of an + * Map the results of an ad-hoc query on the collection for the entity type to a single instance of an * object of the specified type. The first document that matches the query is returned and also removed from * the collection in the database. *

- * The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. + * The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. *

- * The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more + * The query is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more * feature rich {@link Query}. * * @param query @@ -489,7 +490,7 @@ public interface MongoOperations { void insert(Collection batchToSave, String collectionName); /** - * Insert a mixed Collection of objects into a database collection determining the + * Insert a mixed Collection of objects into a database collection determining the * collection name to use based on the class. * * @param collectionToSave @@ -498,7 +499,7 @@ public interface MongoOperations { void insertAll(Collection objectsToSave); /** - * Save the object to the collection for the entity type of the object to save. This will perform an + * Save the object to the collection for the entity type of the object to save. This will perform an * insert if the object is not already present, that is an 'upsert'. *

* The object is converted to the MongoDB native representation using an instance of {@see MongoConverter}. Unless @@ -535,7 +536,7 @@ public interface MongoOperations { void save(Object objectToSave, String collectionName); /** - * Updates the first object that is found in the collection of the entity class that matches the query document with + * Updates the first object that is found in the collection of the entity class that matches the query document with * the provided update document. * @param query * the query document that specifies the criteria used to select a record to be updated @@ -559,7 +560,7 @@ public interface MongoOperations { WriteResult updateFirst(Query query, Update update, String collectionName); /** - * Updates all objects that are found in the collection for the entity class that matches the query document criteria + * Updates all objects that are found in the collection for the entity class that matches the query document criteria * with the provided updated document. * @param query * the query document that specifies the criteria used to select a record to be updated @@ -611,4 +612,10 @@ public interface MongoOperations { */ void remove(Query query, String collectionName); + /** + * Returns the underlying {@link MongoConverter}. + * + * @return + */ + MongoConverter getConverter(); } \ No newline at end of file diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index ed0054f32..858f07882 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.mongodb.core; import static org.springframework.data.mongodb.core.query.Criteria.*; @@ -89,8 +88,8 @@ import org.springframework.util.Assert; public class MongoTemplate implements MongoOperations, ApplicationContextAware { private static final Log LOGGER = LogFactory.getLog(MongoTemplate.class); - private static final String ID = "_id"; + private static final WriteResultChecking DEFAULT_WRITE_RESULT_CHECKING = WriteResultChecking.NONE; @SuppressWarnings("serial") private static final List ITERABLE_CLASSES = new ArrayList() { { @@ -118,11 +117,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { */ private boolean slaveOk = false; - private MongoConverter mongoConverter; - private MappingContext, MongoPersistentProperty> mappingContext; - private MongoDbFactory mongoDbFactory; - private MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator(); - private QueryMapper mapper; + private final MongoConverter mongoConverter; + private final MappingContext, MongoPersistentProperty> mappingContext; + private final MongoDbFactory mongoDbFactory; + private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator(); + private final QueryMapper mapper; private ApplicationEventPublisher eventPublisher; private MongoPersistentEntityIndexCreator indexCreator; @@ -134,20 +133,18 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { * @param databaseName */ public MongoTemplate(Mongo mongo, String databaseName) { - this(new SimpleMongoDbFactory(mongo, databaseName), null, null, null); + this(new SimpleMongoDbFactory(mongo, databaseName), null); } /** - * Constructor used for a template configuration with user credentials in - * the form of + * Constructor used for a template configuration with user credentials in the form of * {@link org.springframework.data.authentication.UserCredentials} * * @param mongo * @param databaseName * @param userCredentials */ - public MongoTemplate(Mongo mongo, String databaseName, - UserCredentials userCredentials) { + public MongoTemplate(Mongo mongo, String databaseName, UserCredentials userCredentials) { this(new SimpleMongoDbFactory(mongo, databaseName, userCredentials)); } @@ -157,96 +154,76 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { * @param mongoDbFactory */ public MongoTemplate(MongoDbFactory mongoDbFactory) { - this(mongoDbFactory, null, null, null); + this(mongoDbFactory, null); } /** - * Constructor used for a basic template configuration + * Constructor used for a basic template configuration. * * @param mongoDbFactory * @param mongoConverter */ - public MongoTemplate(MongoDbFactory mongoDbFactory, - MongoConverter mongoConverter) { - this(mongoDbFactory, mongoConverter, null, null); - } - - /** - * Constructor used for a template configuration with a custom - * {@link MongoConverter} and with a specific - * {@link com.mongodb.WriteConcern} to be used for all database write - * operations - * - * @param mongoDbFactory - * @param mongoConverter - * @param writeConcern - * @param writeResultChecking - */ - MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter, - WriteConcern writeConcern, WriteResultChecking writeResultChecking) { + public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) { Assert.notNull(mongoDbFactory); - // Always need a MongoDbFactory for obtaining instances of DB + this.mongoDbFactory = mongoDbFactory; - // Conversion of DBObject to POJO handled either custom or by default - // (MappingMongoConverter) - if (null == mongoConverter) { - this.mongoConverter = getDefaultMongoConverter(); - } else { - this.mongoConverter = mongoConverter; - } - // We always have a mapping context in the converter, whether it's a - // simple - // one or not + this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter(mongoDbFactory) : mongoConverter; + this.mapper = new QueryMapper(this.mongoConverter); + + // We always have a mapping context in the converter, whether it's a simple one or not mappingContext = this.mongoConverter.getMappingContext(); // We create indexes based on mapping events - if (null != mappingContext - && mappingContext instanceof MongoMappingContext) { - indexCreator = new MongoPersistentEntityIndexCreator( - (MongoMappingContext) mappingContext, mongoDbFactory); + if (null != mappingContext && mappingContext instanceof MongoMappingContext) { + indexCreator = new MongoPersistentEntityIndexCreator((MongoMappingContext) mappingContext, mongoDbFactory); eventPublisher = new MongoMappingEventPublisher(indexCreator); if (mappingContext instanceof ApplicationEventPublisherAware) { - ((ApplicationEventPublisherAware) mappingContext) - .setApplicationEventPublisher(eventPublisher); + ((ApplicationEventPublisherAware) mappingContext).setApplicationEventPublisher(eventPublisher); } } - // WriteConcern + + } + + /** + * Configures the {@link WriteResultChecking} to be used with the template. Setting {@literal null} will reset the + * default of {@value #DEFAULT_WRITE_RESULT_CHECKING}. + * + * @param resultChecking + */ + public void setWriteResultChecking(WriteResultChecking resultChecking) { + this.writeResultChecking = resultChecking == null ? DEFAULT_WRITE_RESULT_CHECKING : resultChecking; + } + + /** + * Configures the {@link WriteConcern} to be used with the template. + * + * @param writeConcern + */ + public void setWriteConcern(WriteConcern writeConcern) { this.writeConcern = writeConcern; - // For converting ID names and values throughout Query objects - mapper = new QueryMapper(this.mongoConverter); - // Track WriteResults? - if (writeResultChecking != null) { - this.writeResultChecking = writeResultChecking; - } - } - private final MongoConverter getDefaultMongoConverter() { - // ToDo: maybe add some additional configurations to this very basic one - MappingMongoConverter converter = new MappingMongoConverter( - mongoDbFactory, new MongoMappingContext()); - converter.afterPropertiesSet(); - return converter; + /** + * TODO: document properly + * + * @param slaveOk + */ + public void setSlaveOk(boolean slaveOk) { + this.slaveOk = slaveOk; } - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - String[] beans = applicationContext - .getBeanNamesForType(MongoPersistentEntityIndexCreator.class); - if ((null == beans || beans.length == 0) - && applicationContext instanceof ConfigurableApplicationContext) { - ((ConfigurableApplicationContext) applicationContext) - .addApplicationListener(indexCreator); + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + String[] beans = applicationContext.getBeanNamesForType(MongoPersistentEntityIndexCreator.class); + if ((null == beans || beans.length == 0) && applicationContext instanceof ConfigurableApplicationContext) { + ((ConfigurableApplicationContext) applicationContext).addApplicationListener(indexCreator); } eventPublisher = applicationContext; if (mappingContext instanceof ApplicationEventPublisherAware) { - ((ApplicationEventPublisherAware) mappingContext) - .setApplicationEventPublisher(eventPublisher); + ((ApplicationEventPublisherAware) mappingContext).setApplicationEventPublisher(eventPublisher); } } /** - * Returns the default - * {@link org.springframework.data.mongodb.core.core.convert.MongoConverter}. + * Returns the default {@link org.springframework.data.mongodb.core.core.convert.MongoConverter}. * * @return */ @@ -254,76 +231,33 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { return this.mongoConverter; } - /** - * Returns the - * {@link org.springframework.data.mongodb.core.MongoDbFactory}. - * - * @return - */ - public MongoDbFactory getDbFactory() { - return this.mongoDbFactory; - } - - public MappingContext, MongoPersistentProperty> getMappingContext() { - return mappingContext; - } - - /* - * (non-Javadoc) - * - * @see org.springframework.data.mongodb.core.core.MongoOperations# - * getDefaultCollectionName() - */ public String getCollectionName(Class entityClass) { return this.determineCollectionName(entityClass); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#executeCommand - * (java.lang.String) - */ public CommandResult executeCommand(String jsonCommand) { return executeCommand((DBObject) JSON.parse(jsonCommand)); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#executeCommand - * (com.mongodb.DBObject) - */ public CommandResult executeCommand(final DBObject command) { CommandResult result = execute(new DbCallback() { - public CommandResult doInDB(DB db) throws MongoException, - DataAccessException { + public CommandResult doInDB(DB db) throws MongoException, DataAccessException { return db.command(command); } }); String error = result.getErrorMessage(); if (error != null) { - // TODO: allow configuration of logging level / throw + // TODO: DATADOC-204 allow configuration of logging level / throw // throw new // InvalidDataAccessApiUsageException("Command execution of " + // command.toString() + " failed: " + error); - LOGGER.warn("Command execution of " + command.toString() - + " failed: " + error); + LOGGER.warn("Command execution of " + command.toString() + " failed: " + error); } return result; } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#execute(org. - * springframework.data.document.mongodb.DBCallback) - */ public T execute(DbCallback action) { Assert.notNull(action); @@ -336,47 +270,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#execute(org. - * springframework.data.document.mongodb.CollectionCallback) - */ public T execute(Class entityClass, CollectionCallback callback) { return execute(determineCollectionName(entityClass), callback); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#execute(org. - * springframework.data.document.mongodb.CollectionCallback, - * java.lang.String) - */ public T execute(String collectionName, CollectionCallback callback) { Assert.notNull(callback); try { - DBCollection collection = getAndPrepareCollection(getDb(), - collectionName); + DBCollection collection = getAndPrepareCollection(getDb(), collectionName); return callback.doInCollection(collection); } catch (RuntimeException e) { throw potentiallyConvertRuntimeException(e); } } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#executeInSession - * (org.springframework.data.mongodb.core.core.DBCallback) - */ public T executeInSession(final DbCallback action) { - return execute(new DbCallback() { public T doInDB(DB db) throws MongoException, DataAccessException { try { @@ -389,127 +299,52 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { }); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#createCollection - * (java.lang.Class) - */ public DBCollection createCollection(Class entityClass) { return createCollection(determineCollectionName(entityClass)); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#createCollection - * (java.lang.Class, - * org.springframework.data.mongodb.core.core.CollectionOptions) - */ - public DBCollection createCollection(Class entityClass, - CollectionOptions collectionOptions) { + public DBCollection createCollection(Class entityClass, CollectionOptions collectionOptions) { return createCollection(determineCollectionName(entityClass), collectionOptions); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#createCollection - * (java.lang.String) - */ public DBCollection createCollection(final String collectionName) { return doCreateCollection(collectionName, new BasicDBObject()); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#createCollection - * (java.lang.String, - * org.springframework.data.mongodb.core.core.CollectionOptions) - */ - public DBCollection createCollection(final String collectionName, - final CollectionOptions collectionOptions) { - return doCreateCollection(collectionName, - convertToDbObject(collectionOptions)); + public DBCollection createCollection(final String collectionName, final CollectionOptions collectionOptions) { + return doCreateCollection(collectionName, convertToDbObject(collectionOptions)); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#getCollection - * (java.lang.String) - */ public DBCollection getCollection(final String collectionName) { return execute(new DbCallback() { - public DBCollection doInDB(DB db) throws MongoException, - DataAccessException { + public DBCollection doInDB(DB db) throws MongoException, DataAccessException { return db.getCollection(collectionName); } }); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#collectionExists - * (java.lang.Class) - */ public boolean collectionExists(Class entityClass) { return collectionExists(determineCollectionName(entityClass)); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#collectionExists - * (java.lang.String) - */ public boolean collectionExists(final String collectionName) { return execute(new DbCallback() { - public Boolean doInDB(DB db) throws MongoException, - DataAccessException { + public Boolean doInDB(DB db) throws MongoException, DataAccessException { return db.collectionExists(collectionName); } }); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#dropCollection - * (java.lang.Class) - */ public void dropCollection(Class entityClass) { - dropCollection(determineCollectionName(entityClass)); - } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#dropCollection - * (java.lang.String) - */ public void dropCollection(String collectionName) { - execute(collectionName, new CollectionCallback() { - public Void doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException { collection.drop(); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Dropped collection [" - + collection.getFullName() + "]"); + LOGGER.debug("Dropped collection [" + collection.getFullName() + "]"); } return null; } @@ -524,12 +359,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { public void ensureIndex(final IndexDefinition indexDefinition, String collectionName) { execute(collectionName, new CollectionCallback() { - public Object doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException { DBObject indexOptions = indexDefinition.getIndexOptions(); if (indexOptions != null) { - collection.ensureIndex(indexDefinition.getIndexKeys(), - indexOptions); + collection.ensureIndex(indexDefinition.getIndexKeys(), indexOptions); } else { collection.ensureIndex(indexDefinition.getIndexKeys()); } @@ -538,32 +371,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { }); } - // Find methods that take a Query to express the query and that return a - // single object. + // Find methods that take a Query to express the query and that return a single object. public T findOne(Query query, Class entityClass) { return findOne(query, entityClass, determineCollectionName(entityClass)); } - public T findOne(Query query, Class entityClass, - String collectionName) { - return doFindOne(collectionName, query.getQueryObject(), - query.getFieldsObject(), entityClass); + public T findOne(Query query, Class entityClass, String collectionName) { + return doFindOne(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass); } - // Find methods that take a Query to express the query and that return a - // List - // of objects. + // Find methods that take a Query to express the query and that return a List of objects. public List find(Query query, Class entityClass) { return find(query, entityClass, determineCollectionName(entityClass)); } - public List find(final Query query, Class entityClass, - String collectionName) { + public List find(final Query query, Class entityClass, String collectionName) { CursorPreparer cursorPreparer = null; - if (query.getSkip() > 0 || query.getLimit() > 0 - || query.getSortObject() != null) { + if (query.getSkip() > 0 || query.getLimit() > 0 || query.getSortObject() != null) { cursorPreparer = new CursorPreparer() { public DBCursor prepare(DBCursor cursor) { @@ -576,8 +402,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { cursorToUse = cursorToUse.limit(query.getLimit()); } if (query.getSortObject() != null) { - cursorToUse = cursorToUse.sort(query - .getSortObject()); + cursorToUse = cursorToUse.sort(query.getSortObject()); } } catch (RuntimeException e) { throw potentiallyConvertRuntimeException(e); @@ -586,52 +411,40 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } }; } - return doFind(collectionName, query.getQueryObject(), - query.getFieldsObject(), entityClass, cursorPreparer); + return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass, cursorPreparer); } - public List find(Query query, Class entityClass, - CursorPreparer preparer, String collectionName) { - return doFind(collectionName, query.getQueryObject(), - query.getFieldsObject(), entityClass, preparer); + public List find(Query query, Class entityClass, CursorPreparer preparer, String collectionName) { + return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), entityClass, preparer); } public T findById(Object id, Class entityClass) { - MongoPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(entityClass); + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityClass); return findById(id, entityClass, persistentEntity.getCollection()); } public T findById(Object id, Class entityClass, String collectionName) { - MongoPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(entityClass); + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityClass); MongoPersistentProperty idProperty = persistentEntity.getIdProperty(); String idKey = idProperty == null ? ID : idProperty.getName(); - return doFindOne(collectionName, new BasicDBObject(idKey, id), null, - entityClass); + return doFindOne(collectionName, new BasicDBObject(idKey, id), null, entityClass); } - // Find methods that take a Query to express the query and that return a - // single object that is - // also removed from the collection in the database. + // Find methods that take a Query to express the query and that return a single object that is also removed from the + // collection in the database. public T findAndRemove(Query query, Class entityClass) { - return findAndRemove(query, entityClass, - determineCollectionName(entityClass)); + return findAndRemove(query, entityClass, determineCollectionName(entityClass)); } - public T findAndRemove(Query query, Class entityClass, - String collectionName) { - return doFindAndRemove(collectionName, query.getQueryObject(), - query.getFieldsObject(), query.getSortObject(), entityClass); + public T findAndRemove(Query query, Class entityClass, String collectionName) { + return doFindAndRemove(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(), + entityClass); } /* * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#insert(java - * .lang .Object) + * @see org.springframework.data.mongodb.core.MongoOperations#insert(java.lang.Object) */ public void insert(Object objectToSave) { ensureNotIterable(objectToSave); @@ -640,10 +453,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { /* * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#insert(java - * .lang .String, java.lang.Object) + * @see org.springframework.data.mongodb.core.MongoOperations#insert(java.lang.Object, java.lang.String) */ public void insert(Object objectToSave, String collectionName) { ensureNotIterable(objectToSave); @@ -652,18 +462,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { protected void ensureNotIterable(Object o) { if (null != o) { - if (o.getClass().isArray() - || ITERABLE_CLASSES.contains(o.getClass().getName())) { - throw new IllegalArgumentException( - "Cannot use a collection here."); + if (o.getClass().isArray() || ITERABLE_CLASSES.contains(o.getClass().getName())) { + throw new IllegalArgumentException("Cannot use a collection here."); } } } /** - * Prepare the collection before any processing is done using it. This - * allows a convenient way to apply settings like slaveOk() etc. Can be - * overridden in sub-classes. + * Prepare the collection before any processing is done using it. This allows a convenient way to apply settings like + * slaveOk() etc. Can be overridden in sub-classes. * * @param collection */ @@ -674,19 +481,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Prepare the WriteConcern before any processing is done using it. This - * allows a convenient way to apply custom settings in sub-classes. + * Prepare the WriteConcern before any processing is done using it. This allows a convenient way to apply custom + * settings in sub-classes. * - * @param writeConcern - * any WriteConcern already configured or null + * @param writeConcern any WriteConcern already configured or null * @return The prepared WriteConcern or null */ protected WriteConcern prepareWriteConcern(WriteConcern writeConcern) { return writeConcern; } - protected void doInsert(String collectionName, T objectToSave, - MongoWriter writer) { + protected void doInsert(String collectionName, T objectToSave, MongoWriter writer) { BasicDBObject dbDoc = new BasicDBObject(); maybeEmitEvent(new BeforeConvertEvent(objectToSave)); @@ -699,52 +504,27 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { maybeEmitEvent(new AfterSaveEvent(objectToSave, dbDoc)); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#insertList(java - * .util.List) - */ public void insert(Collection batchToSave, Class entityClass) { doInsertBatch(determineCollectionName(entityClass), batchToSave, this.mongoConverter); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#insertList(java - * .lang.String, java.util.List) - */ - public void insert(Collection batchToSave, - String collectionName) { + public void insert(Collection batchToSave, String collectionName) { doInsertBatch(collectionName, batchToSave, this.mongoConverter); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#insertAll(java - * .util.Collection) - */ public void insertAll(Collection objectsToSave) { doInsertAll(objectsToSave, this.mongoConverter); } - protected void doInsertAll(Collection listToSave, - MongoWriter writer) { + protected void doInsertAll(Collection listToSave, MongoWriter writer) { Map> objs = new HashMap>(); for (T o : listToSave) { - MongoPersistentEntity entity = mappingContext - .getPersistentEntity(o.getClass()); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(o.getClass()); if (entity == null) { - throw new InvalidDataAccessApiUsageException( - "No Persitent Entity information found for the class " - + o.getClass().getName()); + throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class " + + o.getClass().getName()); } String collection = entity.getCollection(); @@ -762,8 +542,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } } - protected void doInsertBatch(String collectionName, - Collection batchToSave, MongoWriter writer) { + protected void doInsertBatch(String collectionName, Collection batchToSave, MongoWriter writer) { Assert.notNull(writer); @@ -788,30 +567,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#save(java.lang - * .Object) - */ public void save(Object objectToSave) { save(objectToSave, determineEntityCollectionName(objectToSave)); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#save(java.lang - * .String, java.lang.Object) - */ public void save(Object objectToSave, String collectionName) { doSave(collectionName, objectToSave, this.mongoConverter); } - protected void doSave(String collectionName, T objectToSave, - MongoWriter writer) { + protected void doSave(String collectionName, T objectToSave, MongoWriter writer) { BasicDBObject dbDoc = new BasicDBObject(); maybeEmitEvent(new BeforeConvertEvent(objectToSave)); @@ -826,12 +590,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { protected Object insertDBObject(String collectionName, final DBObject dbDoc) { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("insert DBObject containing fields: " + dbDoc.keySet() - + " in collection: " + collectionName); + LOGGER.debug("insert DBObject containing fields: " + dbDoc.keySet() + " in collection: " + collectionName); } return execute(collectionName, new CollectionCallback() { - public Object doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException { WriteConcern writeConcernToUse = prepareWriteConcern(writeConcern); if (writeConcernToUse == null) { collection.insert(dbDoc); @@ -843,26 +605,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { }); } - protected List insertDBObjectList(String collectionName, - final List dbDocList) { + protected List insertDBObjectList(String collectionName, final List dbDocList) { if (dbDocList.isEmpty()) { return Collections.emptyList(); } if (LOGGER.isDebugEnabled()) { - LOGGER.debug("insert list of DBObjects containing " - + dbDocList.size() + " items"); + LOGGER.debug("insert list of DBObjects containing " + dbDocList.size() + " items"); } execute(collectionName, new CollectionCallback() { - public Void doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException { WriteConcern writeConcernToUse = prepareWriteConcern(writeConcern); if (writeConcernToUse == null) { collection.insert(dbDocList); } else { - collection.insert(dbDocList - .toArray((DBObject[]) new BasicDBObject[dbDocList - .size()]), writeConcernToUse); + collection.insert(dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcernToUse); } return null; } @@ -886,8 +643,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { LOGGER.debug("save DBObject containing fields: " + dbDoc.keySet()); } return execute(collectionName, new CollectionCallback() { - public Object doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException { WriteConcern writeConcernToUse = prepareWriteConcern(writeConcern); if (writeConcernToUse == null) { collection.save(dbDoc); @@ -899,91 +655,50 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { }); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#updateFirst(com - * .mongodb.DBObject, com.mongodb.DBObject) - */ - public WriteResult updateFirst(Query query, Update update, - Class entityClass) { - return doUpdate(determineCollectionName(entityClass), query, update, - entityClass, false, false); + public WriteResult updateFirst(Query query, Update update, Class entityClass) { + return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, false); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#updateFirst - * (java .lang.String, com.mongodb.DBObject, com.mongodb.DBObject) - */ - public WriteResult updateFirst(final Query query, - final Update update, final String collectionName) { + public WriteResult updateFirst(final Query query, final Update update, final String collectionName) { return doUpdate(collectionName, query, update, null, false, false); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#updateMulti(com - * .mongodb.DBObject, com.mongodb.DBObject) - */ - public WriteResult updateMulti(Query query, Update update, - Class entityClass) { - return doUpdate(determineCollectionName(entityClass), query, update, - entityClass, false, true); + public WriteResult updateMulti(Query query, Update update, Class entityClass) { + return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, true); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#updateMulti - * (java .lang.String, com.mongodb.DBObject, com.mongodb.DBObject) - */ - public WriteResult updateMulti(final Query query, final Update update, - String collectionName) { + public WriteResult updateMulti(final Query query, final Update update, String collectionName) { return doUpdate(collectionName, query, update, null, false, true); } - protected WriteResult doUpdate(final String collectionName, - final Query query, final Update update, final Class entityClass, - final boolean upsert, final boolean multi) { + protected WriteResult doUpdate(final String collectionName, final Query query, final Update update, + final Class entityClass, final boolean upsert, final boolean multi) { return execute(collectionName, new CollectionCallback() { - public WriteResult doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public WriteResult doInCollection(DBCollection collection) throws MongoException, DataAccessException { DBObject queryObj = query.getQueryObject(); DBObject updateObj = update.getUpdateObject(); String idProperty = "id"; if (null != entityClass) { - idProperty = getPersistentEntity(entityClass) - .getIdProperty().getName(); + idProperty = getPersistentEntity(entityClass).getIdProperty().getName(); } for (String key : queryObj.keySet()) { if (idProperty.equals(key)) { // This is an ID field - queryObj.put(ID, mongoConverter - .maybeConvertObject(queryObj.get(key))); + queryObj.put(ID, mongoConverter.maybeConvertObject(queryObj.get(key))); queryObj.removeField(key); } else { - queryObj.put(key, mongoConverter - .maybeConvertObject(queryObj.get(key))); + queryObj.put(key, mongoConverter.maybeConvertObject(queryObj.get(key))); } } for (String key : updateObj.keySet()) { - updateObj.put(key, mongoConverter - .maybeConvertObject(updateObj.get(key))); + updateObj.put(key, mongoConverter.maybeConvertObject(updateObj.get(key))); } if (LOGGER.isDebugEnabled()) { - LOGGER.debug("calling update using query: " + queryObj - + " and update: " + updateObj + " in collection: " + LOGGER.debug("calling update using query: " + queryObj + " and update: " + updateObj + " in collection: " + collectionName); } @@ -996,28 +711,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { wr = collection.update(queryObj, updateObj); } } else { - wr = collection.update(queryObj, updateObj, upsert, multi, - writeConcernToUse); + wr = collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse); } - handleAnyWriteResultErrors(wr, queryObj, "update with '" - + updateObj + "'"); + handleAnyWriteResultErrors(wr, queryObj, "update with '" + updateObj + "'"); return wr; } }); } - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.core.MongoOperations#remove(java.lang.Object) - */ public void remove(Object object) { - + if (object == null) { return; } - - remove(new Query(where(getIdPropertyName(object)) - .is(getIdValue(object))), object.getClass()); + + remove(new Query(where(getIdPropertyName(object)).is(getIdValue(object))), object.getClass()); } public void remove(Query query, Class entityClass) { @@ -1025,23 +733,19 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { doRemove(determineCollectionName(entityClass), query, entityClass); } - protected void doRemove(String collectionName, final Query query, - Class entityClass) { + protected void doRemove(String collectionName, final Query query, Class entityClass) { if (query == null) { - throw new InvalidDataAccessApiUsageException( - "Query passed in to remove can't be null"); + throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null"); } final DBObject queryObject = query.getQueryObject(); final MongoPersistentEntity entity = getPersistentEntity(entityClass); execute(collectionName, new CollectionCallback() { - public Void doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException { DBObject dboq = mapper.getMappedObject(queryObject, entity); WriteResult wr = null; WriteConcern writeConcernToUse = prepareWriteConcern(writeConcern); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("remove using query: " + queryObject - + " in collection: " + collection.getName()); + LOGGER.debug("remove using query: " + queryObject + " in collection: " + collection.getName()); } if (writeConcernToUse == null) { wr = collection.remove(dboq); @@ -1054,40 +758,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { }); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#remove(java - * .lang .String, com.mongodb.DBObject) - */ public void remove(final Query query, String collectionName) { doRemove(collectionName, query, null); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.mongodb.core.core.MongoOperations#getCollection - * (java.lang.Class) - */ public List findAll(Class entityClass) { - return executeFindMultiInternal(new FindCallback(null), null, - new ReadDbObjectCallback(mongoConverter, entityClass), - determineCollectionName(entityClass)); + return executeFindMultiInternal(new FindCallback(null), null, new ReadDbObjectCallback(mongoConverter, + entityClass), determineCollectionName(entityClass)); } public List findAll(Class entityClass, String collectionName) { - return executeFindMultiInternal(new FindCallback(null), null, - new ReadDbObjectCallback(mongoConverter, entityClass), - collectionName); + return executeFindMultiInternal(new FindCallback(null), null, new ReadDbObjectCallback(mongoConverter, + entityClass), collectionName); } public Set getCollectionNames() { return execute(new DbCallback>() { - public Set doInDB(DB db) throws MongoException, - DataAccessException { + public Set doInDB(DB db) throws MongoException, DataAccessException { return db.getCollectionNames(); } }); @@ -1110,17 +797,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { * @param collectionOptions * @return the collection that was created */ - protected DBCollection doCreateCollection(final String collectionName, - final DBObject collectionOptions) { + protected DBCollection doCreateCollection(final String collectionName, final DBObject collectionOptions) { return execute(new DbCallback() { - public DBCollection doInDB(DB db) throws MongoException, - DataAccessException { - DBCollection coll = db.createCollection(collectionName, - collectionOptions); + public DBCollection doInDB(DB db) throws MongoException, DataAccessException { + DBCollection coll = db.createCollection(collectionName, collectionOptions); // TODO: Emit a collection created event if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Created collection [" + coll.getFullName() - + "]"); + LOGGER.debug("Created collection [" + coll.getFullName() + "]"); } return coll; } @@ -1128,109 +811,80 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Map the results of an ad-hoc query on the default MongoDB collection to - * an object using the template's converter + * Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter *

- * The query document is specified as a standard DBObject and so is the - * fields specification. + * The query document is specified as a standard DBObject and so is the fields specification. * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a - * record - * @param fields - * the document that specifies the fields to be returned - * @param entityClass - * the parameterized type of the returned list. + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param fields the document that specifies the fields to be returned + * @param entityClass the parameterized type of the returned list. * @return the List of converted objects. */ - protected T doFindOne(String collectionName, DBObject query, - DBObject fields, Class entityClass) { + protected T doFindOne(String collectionName, DBObject query, DBObject fields, Class entityClass) { MongoReader readerToUse = this.mongoConverter; - MongoPersistentEntity entity = mappingContext - .getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); DBObject mappedQuery = mapper.getMappedObject(query, entity); - return executeFindOneInternal(new FindOneCallback(mappedQuery, fields), - new ReadDbObjectCallback(readerToUse, entityClass), - collectionName); + return executeFindOneInternal(new FindOneCallback(mappedQuery, fields), new ReadDbObjectCallback(readerToUse, + entityClass), collectionName); } /** - * Map the results of an ad-hoc query on the default MongoDB collection to a - * List of the specified type. + * Map the results of an ad-hoc query on the default MongoDB collection to a List of the specified type. *

- * The object is converted from the MongoDB native representation using an - * instance of {@see MongoConverter}. Unless configured otherwise, an - * instance of SimpleMongoConverter will be used. + * The object is converted from the MongoDB native representation using an instance of {@see MongoConverter}. Unless + * configured otherwise, an instance of SimpleMongoConverter will be used. *

- * The query document is specified as a standard DBObject and so is the - * fields specification. + * The query document is specified as a standard DBObject and so is the fields specification. *

* Can be overridden by subclasses. * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a - * record - * @param fields - * the document that specifies the fields to be returned - * @param entityClass - * the parameterized type of the returned list. - * @param preparer - * allows for customization of the DBCursor used when iterating - * over the result set, (apply limits, skips and so on). + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param fields the document that specifies the fields to be returned + * @param entityClass the parameterized type of the returned list. + * @param preparer allows for customization of the DBCursor used when iterating over the result set, (apply limits, + * skips and so on). * @return the List of converted objects. */ - protected List doFind(String collectionName, DBObject query, - DBObject fields, Class entityClass, CursorPreparer preparer) { - MongoPersistentEntity entity = mappingContext - .getPersistentEntity(entityClass); + protected List doFind(String collectionName, DBObject query, DBObject fields, Class entityClass, + CursorPreparer preparer) { + return doFind(collectionName, query, fields, entityClass, preparer, new ReadDbObjectCallback(mongoConverter, + entityClass)); + } + + protected List doFind(String collectionName, DBObject query, DBObject fields, Class entityClass, + CursorPreparer preparer, DbObjectCallback objectCallback) { + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("find using query: " + query + " fields: " + fields - + " for class: " + entityClass + " in collection: " - + collectionName); + LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + entityClass + + " in collection: " + collectionName); } - return executeFindMultiInternal( - new FindCallback(mapper.getMappedObject(query, entity), fields), - preparer, new ReadDbObjectCallback(mongoConverter, - entityClass), collectionName); + return executeFindMultiInternal(new FindCallback(mapper.getMappedObject(query, entity), fields), preparer, + objectCallback, collectionName); } /** - * Map the results of an ad-hoc query on the default MongoDB collection to a - * List using the template's converter. + * Map the results of an ad-hoc query on the default MongoDB collection to a List using the template's converter. *

- * The query document is specified as a standard DBObject and so is the - * fields specification. + * The query document is specified as a standard DBObject and so is the fields specification. * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a - * record - * @param fields - * the document that specifies the fields to be returned - * @param entityClass - * the parameterized type of the returned list. + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param fields the document that specifies the fields to be returned + * @param entityClass the parameterized type of the returned list. * @return the List of converted objects. */ - protected List doFind(String collectionName, DBObject query, - DBObject fields, Class entityClass) { + protected List doFind(String collectionName, DBObject query, DBObject fields, Class entityClass) { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("find using query: " + query + " fields: " + fields - + " for class: " + entityClass + " in collection: " - + collectionName); + LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + entityClass + + " in collection: " + collectionName); } MongoReader readerToUse = this.mongoConverter; - MongoPersistentEntity entity = mappingContext - .getPersistentEntity(entityClass); - return executeFindMultiInternal( - new FindCallback(mapper.getMappedObject(query, entity), fields), - null, new ReadDbObjectCallback(readerToUse, entityClass), - collectionName); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); + return executeFindMultiInternal(new FindCallback(mapper.getMappedObject(query, entity), fields), null, + new ReadDbObjectCallback(readerToUse, entityClass), collectionName); } protected DBObject convertToDbObject(CollectionOptions collectionOptions) { @@ -1250,57 +904,41 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Map the results of an ad-hoc query on the default MongoDB collection to - * an object using the template's converter. The first document that matches - * the query is returned and also removed from the collection in the - * database. + * Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter. + * The first document that matches the query is returned and also removed from the collection in the database. *

- * The query document is specified as a standard DBObject and so is the - * fields specification. + * The query document is specified as a standard DBObject and so is the fields specification. * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a - * record - * @param entityClass - * the parameterized type of the returned list. + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param entityClass the parameterized type of the returned list. * @return the List of converted objects. */ - protected T doFindAndRemove(String collectionName, DBObject query, - DBObject fields, DBObject sort, Class entityClass) { + protected T doFindAndRemove(String collectionName, DBObject query, DBObject fields, DBObject sort, + Class entityClass) { MongoReader readerToUse = this.mongoConverter; if (LOGGER.isDebugEnabled()) { - LOGGER.debug("findAndRemove using query: " + query + " fields: " - + fields + " sort: " + sort + " for class: " + entityClass - + " in collection: " + collectionName); + LOGGER.debug("findAndRemove using query: " + query + " fields: " + fields + " sort: " + sort + " for class: " + + entityClass + " in collection: " + collectionName); } - MongoPersistentEntity entity = mappingContext - .getPersistentEntity(entityClass); - return executeFindOneInternal( - new FindAndRemoveCallback( - mapper.getMappedObject(query, entity), fields, sort), - new ReadDbObjectCallback(readerToUse, entityClass), - collectionName); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); + return executeFindOneInternal(new FindAndRemoveCallback(mapper.getMappedObject(query, entity), fields, sort), + new ReadDbObjectCallback(readerToUse, entityClass), collectionName); } protected Object getIdValue(Object object) { - MongoPersistentEntity entity = mappingContext - .getPersistentEntity(object.getClass()); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(object.getClass()); MongoPersistentProperty idProp = entity.getIdProperty(); if (idProp == null) { - throw new MappingException( - "No id property found for object of type " - + entity.getType().getName()); + throw new MappingException("No id property found for object of type " + entity.getType().getName()); } ConversionService service = mongoConverter.getConversionService(); try { - return BeanWrapper.create(object, service).getProperty(idProp, - Object.class, true); + return BeanWrapper.create(object, service).getProperty(idProp, Object.class, true); } catch (IllegalAccessException e) { throw new MappingException(e.getMessage(), e); } catch (InvocationTargetException e) { @@ -1310,11 +948,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { protected String getIdPropertyName(Object object) { Assert.notNull(object); - - MongoPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(object.getClass()); + + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(object.getClass()); MongoPersistentProperty idProperty = persistentEntity.getIdProperty(); - + return idProperty == null ? ID : idProperty.getName(); } @@ -1330,17 +967,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { return; } - MongoPersistentProperty idProp = getIdPropertyFor(savedObject - .getClass()); + MongoPersistentProperty idProp = getIdPropertyFor(savedObject.getClass()); if (idProp == null) { return; } try { - BeanWrapper.create(savedObject, - mongoConverter.getConversionService()).setProperty(idProp, - id); + BeanWrapper.create(savedObject, mongoConverter.getConversionService()).setProperty(idProp, id); return; } catch (IllegalAccessException e) { throw new MappingException(e.getMessage(), e); @@ -1360,33 +994,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Internal method using callbacks to do queries against the datastore that - * requires reading a single object from a collection of objects. It will - * take the following steps + * Internal method using callbacks to do queries against the datastore that requires reading a single object from a + * collection of objects. It will take the following steps *

    *
  1. Execute the given {@link ConnectionCallback} for a {@link DBObject}.
  2. - *
  3. Apply the given {@link DbObjectCallback} to each of the - * {@link DBObject}s to obtain the result.
  4. + *
  5. Apply the given {@link DbObjectCallback} to each of the {@link DBObject}s to obtain the result.
  6. *
      * * @param - * @param collectionCallback - * the callback to retrieve the {@link DBObject} with - * @param objectCallback - * the {@link DbObjectCallback} to transform {@link DBObject}s - * into the actual domain type - * @param collectionName - * the collection to be queried + * @param collectionCallback the callback to retrieve the {@link DBObject} with + * @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 executeFindOneInternal( - CollectionCallback collectionCallback, + private T executeFindOneInternal(CollectionCallback collectionCallback, DbObjectCallback objectCallback, String collectionName) { try { - T result = objectCallback.doWith(collectionCallback - .doInCollection(getAndPrepareCollection(getDb(), - collectionName))); + T result = objectCallback.doWith(collectionCallback.doInCollection(getAndPrepareCollection(getDb(), + collectionName))); return result; } catch (RuntimeException e) { throw potentiallyConvertRuntimeException(e); @@ -1394,40 +1020,28 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Internal method using callback to do queries against the datastore that - * requires reading a collection of objects. It will take the following - * steps + * Internal method using callback to do queries against the datastore that requires reading a collection of objects. + * It will take the following steps *
        *
      1. Execute the given {@link ConnectionCallback} for a {@link DBCursor}.
      2. - *
      3. Prepare that {@link DBCursor} with the given {@link CursorPreparer} - * (will be skipped if {@link CursorPreparer} is {@literal null}
      4. - *
      5. Iterate over the {@link DBCursor} and applies the given - * {@link DbObjectCallback} to each of the {@link DBObject}s collecting the - * actual result {@link List}.
      6. + *
      7. Prepare that {@link DBCursor} with the given {@link CursorPreparer} (will be skipped if {@link CursorPreparer} + * is {@literal null}
      8. + *
      9. Iterate over the {@link DBCursor} and applies the given {@link DbObjectCallback} to each of the + * {@link DBObject}s collecting the actual result {@link List}.
      10. *
          * * @param - * @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 + * @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 List executeFindMultiInternal( - CollectionCallback collectionCallback, - CursorPreparer preparer, DbObjectCallback objectCallback, - String collectionName) { + private List executeFindMultiInternal(CollectionCallback collectionCallback, + CursorPreparer preparer, DbObjectCallback objectCallback, String collectionName) { try { - DBCursor cursor = collectionCallback - .doInCollection(getAndPrepareCollection(getDb(), - collectionName)); + DBCursor cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName)); if (preparer != null) { cursor = preparer.prepare(cursor); @@ -1465,16 +1079,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { if (entityClass == null) { throw new InvalidDataAccessApiUsageException( - "No class parameter provided, entity collection can't be determined for " - + entityClass); + "No class parameter provided, entity collection can't be determined for " + entityClass); } - MongoPersistentEntity entity = mappingContext - .getPersistentEntity(entityClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); if (entity == null) { - throw new InvalidDataAccessApiUsageException( - "No Persitent Entity information found for the class " - + entityClass.getName()); + throw new InvalidDataAccessApiUsageException("No Persitent Entity information found for the class " + + entityClass.getName()); } return entity.getCollection(); } @@ -1482,31 +1093,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { /** * Checks and handles any errors. *

          - * TODO: current implementation logs errors - will be configurable to log - * warning, errors or throw exception in later versions + * TODO: current implementation logs errors - will be configurable to log warning, errors or throw exception in later + * versions */ - private void handleAnyWriteResultErrors(WriteResult wr, DBObject query, - String operation) { + private void handleAnyWriteResultErrors(WriteResult wr, DBObject query, String operation) { if (WriteResultChecking.NONE == this.writeResultChecking) { return; } String error = wr.getError(); int n = wr.getN(); if (error != null) { - String message = "Execution of '" - + operation - + (query == null ? "" : "' using '" + query.toString() - + "' query") + " failed: " + error; + String message = "Execution of '" + operation + (query == null ? "" : "' using '" + query.toString() + "' query") + + " failed: " + error; if (WriteResultChecking.EXCEPTION == this.writeResultChecking) { throw new DataIntegrityViolationException(message); } else { LOGGER.error(message); } } else if (n == 0) { - String message = "Execution of '" - + operation - + (query == null ? "" : "' using '" + query.toString() - + "' query") + String message = "Execution of '" + operation + (query == null ? "" : "' using '" + query.toString() + "' query") + " did not succeed: 0 documents updated"; if (WriteResultChecking.EXCEPTION == this.writeResultChecking) { throw new DataIntegrityViolationException(message); @@ -1514,37 +1119,39 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { LOGGER.warn(message); } } - } /** - * 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. + * 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); + private RuntimeException potentiallyConvertRuntimeException(RuntimeException ex) { + RuntimeException resolved = this.exceptionTranslator.translateExceptionIfPossible(ex); return resolved == null ? ex : resolved; } + private static final MongoConverter getDefaultMongoConverter(MongoDbFactory factory) { + // ToDo: maybe add some additional configurations to this very basic one + MappingMongoConverter converter = new MappingMongoConverter(factory, new MongoMappingContext()); + converter.afterPropertiesSet(); + return converter; + } + + // Callback implementations + /** - * Simple {@link CollectionCallback} that takes a query {@link DBObject} - * plus an optional fields specification {@link DBObject} and executes that - * against the {@link DBCollection}. + * Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification + * {@link DBObject} and executes that against the {@link DBCollection}. * * @author Oliver Gierke * @author Thomas Risberg */ - private static class FindOneCallback implements - CollectionCallback { + private static class FindOneCallback implements CollectionCallback { private final DBObject query; - private final DBObject fields; public FindOneCallback(DBObject query, DBObject fields) { @@ -1552,18 +1159,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { this.fields = fields; } - public DBObject doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public DBObject doInCollection(DBCollection collection) throws MongoException, DataAccessException { if (fields == null) { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("findOne using query: " + query - + " in db.collection: " + collection.getFullName()); + LOGGER.debug("findOne using query: " + query + " in db.collection: " + collection.getFullName()); } return collection.findOne(query); } else { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("findOne using query: " + query + " fields: " - + fields + " in db.collection: " + LOGGER.debug("findOne using query: " + query + " fields: " + fields + " in db.collection: " + collection.getFullName()); } return collection.findOne(query, fields); @@ -1572,9 +1176,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Simple {@link CollectionCallback} that takes a query {@link DBObject} - * plus an optional fields specification {@link DBObject} and executes that - * against the {@link DBCollection}. + * Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification + * {@link DBObject} and executes that against the {@link DBCollection}. * * @author Oliver Gierke * @author Thomas Risberg @@ -1594,8 +1197,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { this.fields = fields; } - public DBCursor doInCollection(DBCollection collection) - throws MongoException, DataAccessException { + public DBCursor doInCollection(DBCollection collection) throws MongoException, DataAccessException { if (fields == null) { return collection.find(query); } else { @@ -1605,32 +1207,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Simple {@link CollectionCallback} that takes a query {@link DBObject} - * plus an optional fields specification {@link DBObject} and executes that - * against the {@link DBCollection}. + * Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification + * {@link DBObject} and executes that against the {@link DBCollection}. * * @author Thomas Risberg */ - private static class FindAndRemoveCallback implements - CollectionCallback { + private static class FindAndRemoveCallback implements CollectionCallback { private final DBObject query; - private final DBObject fields; - private final DBObject sort; - public FindAndRemoveCallback(DBObject query, DBObject fields, - DBObject sort) { + public FindAndRemoveCallback(DBObject query, DBObject fields, DBObject sort) { this.query = query; this.fields = fields; this.sort = sort; } - public DBObject doInCollection(DBCollection collection) - throws MongoException, DataAccessException { - return collection.findAndModify(query, fields, sort, true, null, - false, false); + public DBObject doInCollection(DBCollection collection) throws MongoException, DataAccessException { + return collection.findAndModify(query, fields, sort, true, null, false, false); } } @@ -1646,8 +1241,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Simple {@link DbObjectCallback} that will transform {@link DBObject} into - * the given target type using the given {@link MongoReader}. + * Simple {@link DbObjectCallback} that will transform {@link DBObject} into the given target type using the given + * {@link MongoReader}. * * @author Oliver Gierke */ @@ -1673,16 +1268,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } } - public void setWriteResultChecking(WriteResultChecking resultChecking) { - this.writeResultChecking = resultChecking; - } - public void setWriteConcern(WriteConcern writeConcern) { - this.writeConcern = writeConcern; - } - public void setSlaveOk(boolean slaveOk) { - this.slaveOk = slaveOk; - } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java index 4e3a4cff2..cef92000f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java @@ -104,7 +104,7 @@ public class QueryMapper { // $or/$nor BasicBSONList conditions = (BasicBSONList) value; BasicBSONList newConditions = new BasicBSONList(); - Iterator iter = conditions.iterator(); + Iterator iter = conditions.iterator(); while (iter.hasNext()) { newConditions.add(getMappedObject((DBObject) iter.next(), entity)); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index d7ab98c4a..d29596384 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -40,6 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.mongodb.InvalidMongoDbApiUsageException; +import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.CollectionCallback; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.WriteResultChecking; @@ -68,10 +69,9 @@ public class MongoTemplateTests { @Autowired MongoTemplate template; - - MongoTemplate mappingTemplate; - - MongoTemplate simpleTemplate; + @Autowired + MongoDbFactory factory; + MongoTemplate mappingTemplate, simpleTemplate; @Rule public ExpectedException thrown = ExpectedException.none(); @@ -88,13 +88,13 @@ public class MongoTemplateTests { PersonWithIdPropertyOfPrimitiveLong.class))); mappingContext.afterPropertiesSet(); - MappingMongoConverter mappingConverter = new MappingMongoConverter(template.getDbFactory(), mappingContext); + MappingMongoConverter mappingConverter = new MappingMongoConverter(factory, mappingContext); mappingConverter.afterPropertiesSet(); - this.mappingTemplate = new MongoTemplate(template.getDbFactory(), mappingConverter); + this.mappingTemplate = new MongoTemplate(factory, mappingConverter); SimpleMongoConverter simpleConverter = new SimpleMongoConverter(); simpleConverter.afterPropertiesSet(); - this.simpleTemplate = new MongoTemplate(template.getDbFactory(), simpleConverter); + this.simpleTemplate = new MongoTemplate(factory, simpleConverter); } @Before @@ -128,7 +128,7 @@ public class MongoTemplateTests { @Test public void updateFailure() throws Exception { - MongoTemplate mongoTemplate = new MongoTemplate(template.getDbFactory()); + MongoTemplate mongoTemplate = new MongoTemplate(factory); mongoTemplate.setWriteResultChecking(WriteResultChecking.EXCEPTION); Person person = new Person("Oliver2"); @@ -746,7 +746,7 @@ public class MongoTemplateTests { return null; } }); - MongoTemplate slaveTemplate = new MongoTemplate(this.template.getDbFactory()); + MongoTemplate slaveTemplate = new MongoTemplate(factory); slaveTemplate.setSlaveOk(true); slaveTemplate.execute("slaveOkTest", new CollectionCallback() { public Object doInCollection(DBCollection collection) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java index 751469fb3..234e06a3d 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java @@ -47,6 +47,7 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Order; import org.springframework.data.mongodb.core.query.Query; +import org.springframework.test.util.ReflectionTestUtils; /** * @author Jon Brisbin @@ -84,7 +85,7 @@ public class MappingTests { } applicationContext = new ClassPathXmlApplicationContext("/mapping.xml"); template = applicationContext.getBean(MongoTemplate.class); - mappingContext = (MongoMappingContext) template.getMappingContext(); + mappingContext = (MongoMappingContext) ReflectionTestUtils.getField(template, "mappingContext"); } @Test