From cffc27d83a28173e8a1880e0130cc24df3b36904 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 10 Dec 2012 19:25:58 +0900 Subject: [PATCH] DATAMONGO-590 - Code cleanups in MongoTemplate and error handling APIs. --- .../data/mongodb/core/MongoAction.java | 58 ++--- .../mongodb/core/MongoActionOperation.java | 4 +- .../data/mongodb/core/MongoTemplate.java | 212 ++++++++---------- .../mongodb/core/SimpleMongoDbFactory.java | 4 +- .../mongodb/core/WriteConcernResolver.java | 18 +- .../mongodb/core/WriteResultChecking.java | 23 ++ .../data/mongodb/core/MongoTemplateTests.java | 21 +- 7 files changed, 167 insertions(+), 173 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java index 140ed2ed4..e1ffbad73 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -13,59 +13,53 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.mongodb.core; +import org.springframework.util.Assert; + import com.mongodb.DBObject; import com.mongodb.WriteConcern; /** * Represents an action taken against the collection. Used by {@link WriteConcernResolver} to determine a custom - * WriteConcern based on this information. - * - * Properties that will always be not-null are collectionName and defaultWriteConcern. The EntityClass is null only for - * the MongoActionOperaton.INSERT_LIST. - * + * {@link WriteConcern} based on this information. * * * @author Mark Pollack - * + * @author Oliver Gierke */ public class MongoAction { - private String collectionName; - - private WriteConcern defaultWriteConcern; - - private Class entityClass; - - private MongoActionOperation mongoActionOperation; - - private DBObject query; - - private DBObject document; + private final String collectionName; + private final WriteConcern defaultWriteConcern; + private final Class entityType; + private final MongoActionOperation mongoActionOperation; + private final DBObject query; + private final DBObject document; /** - * Create an instance of a MongoAction + * Create an instance of a {@link MongoAction}. * - * @param defaultWriteConcern the default write concern + * @param defaultWriteConcern the default write concern. * @param mongoActionOperation action being taken against the collection - * @param collectionName the collection name - * @param entityClass the POJO that is being operated against + * @param collectionName the collection name, must not be {@literal null} or empty. + * @param entityType the POJO that is being operated against * @param document the converted DBObject from the POJO or Spring Update object * @param query the converted DBOjbect from the Spring Query object */ public MongoAction(WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation, - String collectionName, Class entityClass, DBObject document, DBObject query) { - super(); + String collectionName, Class entityType, DBObject document, DBObject query) { + + Assert.hasText(collectionName, "Collection name must not be null or empty!"); + this.defaultWriteConcern = defaultWriteConcern; this.mongoActionOperation = mongoActionOperation; this.collectionName = collectionName; - this.entityClass = entityClass; + this.entityType = entityType; this.query = query; this.document = document; } @@ -78,8 +72,16 @@ public class MongoAction { return defaultWriteConcern; } + /** + * @deprecated use {@link #getEntityType()} instead. + */ + @Deprecated public Class getEntityClass() { - return entityClass; + return entityType; + } + + public Class getEntityType() { + return entityType; } public MongoActionOperation getMongoActionOperation() { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoActionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoActionOperation.java index 7dd3f6ca6..c12752152 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoActionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoActionOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -20,8 +20,8 @@ package org.springframework.data.mongodb.core; * for a given mutating operation * * @author Mark Pollack + * @author Oliver Gierke * @see MongoAction - * */ public enum MongoActionOperation { 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 2dc4a5e9f..2dd85c7f4 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 @@ -116,7 +116,7 @@ import com.mongodb.util.JSONParseException; public class MongoTemplate implements MongoOperations, ApplicationContextAware { private static final Logger LOGGER = LoggerFactory.getLogger(MongoTemplate.class); - private static final String ID = "_id"; + private static final String ID_FIELD = "_id"; private static final WriteResultChecking DEFAULT_WRITE_RESULT_CHECKING = WriteResultChecking.NONE; private static final Collection ITERABLE_CLASSES; @@ -130,32 +130,16 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { ITERABLE_CLASSES = Collections.unmodifiableCollection(iterableClasses); } - /* - * WriteConcern to be used for write operations if it has been specified. - * Otherwise we should not use a WriteConcern defaulting to the one set for - * the DB or Collection. - */ - private WriteConcern writeConcern = null; - - private WriteConcernResolver writeConcernResolver = new DefaultWriteConcernResolver(); - - /* - * WriteResultChecking to be used for write operations if it has been - * specified. Otherwise we should not do any checking. - */ - private WriteResultChecking writeResultChecking = WriteResultChecking.NONE; - - /** - * Set the ReadPreference when operating on a collection. See {@link #prepareCollection(DBCollection)} - */ - private ReadPreference readPreference = null; - private final MongoConverter mongoConverter; private final MappingContext, MongoPersistentProperty> mappingContext; private final MongoDbFactory mongoDbFactory; private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator(); private final QueryMapper mapper; + private WriteConcern writeConcern; + private WriteConcernResolver writeConcernResolver = DefaultWriteConcernResolver.INSTANCE; + private WriteResultChecking writeResultChecking = WriteResultChecking.NONE; + private ReadPreference readPreference; private ApplicationEventPublisher eventPublisher; private ResourceLoader resourceLoader; private MongoPersistentEntityIndexCreator indexCreator; @@ -163,8 +147,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { /** * Constructor used for a basic template configuration * - * @param mongo - * @param databaseName + * @param mongo must not be {@literal null}. + * @param databaseName must not be {@literal null} or empty. */ public MongoTemplate(Mongo mongo, String databaseName) { this(new SimpleMongoDbFactory(mongo, databaseName), null); @@ -174,8 +158,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { * Constructor used for a template configuration with user credentials in the form of * {@link org.springframework.data.authentication.UserCredentials} * - * @param mongo - * @param databaseName + * @param mongo must not be {@literal null}. + * @param databaseName must not be {@literal null} or empty. * @param userCredentials */ public MongoTemplate(Mongo mongo, String databaseName, UserCredentials userCredentials) { @@ -183,9 +167,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Constructor used for a basic template configuration + * Constructor used for a basic template configuration. * - * @param mongoDbFactory + * @param mongoDbFactory must not be {@literal null}. */ public MongoTemplate(MongoDbFactory mongoDbFactory) { this(mongoDbFactory, null); @@ -194,7 +178,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { /** * Constructor used for a basic template configuration. * - * @param mongoDbFactory + * @param mongoDbFactory must not be {@literal null}. * @param mongoConverter */ public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) { @@ -228,7 +212,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Configures the {@link WriteConcern} to be used with the template. + * Configures the {@link WriteConcern} to be used with the template. If none is configured the {@link WriteConcern} + * configured on the {@link MongoDbFactory} will apply. If you configured a {@link Mongo} instance no + * {@link WriteConcern} will be used. * * @param writeConcern */ @@ -276,7 +262,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { * can be found we manually add the internally created one as {@link ApplicationListener} to make sure indexes get * created appropriately for entity types persisted through this {@link MongoTemplate} instance. * - * @param context + * @param context must not be {@literal null}. */ private void prepareIndexCreator(ApplicationContext context) { @@ -512,7 +498,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { public T findById(Object id, Class entityClass, String collectionName) { MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityClass); MongoPersistentProperty idProperty = persistentEntity == null ? null : persistentEntity.getIdProperty(); - String idKey = idProperty == null ? ID : idProperty.getName(); + String idKey = idProperty == null ? ID_FIELD : idProperty.getName(); return doFindOne(collectionName, new BasicDBObject(idKey, id), null, entityClass); } @@ -799,7 +785,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { this.mongoConverter.write(objectToSave, dbObject); maybeEmitEvent(new BeforeSaveEvent(objectToSave, dbObject)); - Update update = Update.fromDBObject(dbObject, ID); + Update update = Update.fromDBObject(dbObject, ID_FIELD); updateFirst(query, update, objectToSave.getClass()); maybeEmitEvent(new AfterSaveEvent(objectToSave, dbObject)); @@ -834,21 +820,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { protected Object insertDBObject(final String collectionName, final DBObject dbDoc, final Class entityClass) { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("insert DBObject containing fields: " + dbDoc.keySet() + " in collection: " + collectionName); + LOGGER.debug("Inserting DBObject containing fields: " + dbDoc.keySet() + " in collection: " + collectionName); } return execute(collectionName, new CollectionCallback() { public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException { MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT, collectionName, entityClass, dbDoc, null); WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction); - WriteResult wr; - if (writeConcernToUse == null) { - wr = collection.insert(dbDoc); - } else { - wr = collection.insert(dbDoc, writeConcernToUse); - } - handleAnyWriteResultErrors(wr, dbDoc, "insert"); - return dbDoc.get(ID); + WriteResult writeResult = writeConcernToUse == null ? collection.insert(dbDoc) : collection.insert(dbDoc, + writeConcernToUse); + handleAnyWriteResultErrors(writeResult, dbDoc, MongoActionOperation.INSERT); + return dbDoc.get(ID_FIELD); } }); } @@ -859,27 +841,23 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } if (LOGGER.isDebugEnabled()) { - LOGGER.debug("insert list of DBObjects containing " + dbDocList.size() + " items"); + LOGGER.debug("Inserting list of DBObjects containing " + dbDocList.size() + " items"); } execute(collectionName, new CollectionCallback() { public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException { MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.INSERT_LIST, collectionName, null, null, null); WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction); - WriteResult wr; - if (writeConcernToUse == null) { - wr = collection.insert(dbDocList); - } else { - wr = collection.insert(dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcernToUse); - } - handleAnyWriteResultErrors(wr, null, "insert_list"); + WriteResult writeResult = writeConcernToUse == null ? collection.insert(dbDocList) : collection.insert( + dbDocList.toArray((DBObject[]) new BasicDBObject[dbDocList.size()]), writeConcernToUse); + handleAnyWriteResultErrors(writeResult, null, MongoActionOperation.INSERT_LIST); return null; } }); List ids = new ArrayList(); for (DBObject dbo : dbDocList) { - Object id = dbo.get(ID); + Object id = dbo.get(ID_FIELD); if (id instanceof ObjectId) { ids.add((ObjectId) id); } else { @@ -892,21 +870,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { protected Object saveDBObject(final String collectionName, final DBObject dbDoc, final Class entityClass) { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("save DBObject containing fields: " + dbDoc.keySet()); + LOGGER.debug("Saving DBObject containing fields: " + dbDoc.keySet()); } return execute(collectionName, new CollectionCallback() { public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException { MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.SAVE, collectionName, entityClass, dbDoc, null); WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction); - WriteResult wr; - if (writeConcernToUse == null) { - wr = collection.save(dbDoc); - } else { - wr = collection.save(dbDoc, writeConcernToUse); - } - handleAnyWriteResultErrors(wr, dbDoc, "save"); - return dbDoc.get(ID); + WriteResult writeResult = writeConcernToUse == null ? collection.save(dbDoc) : collection.save(dbDoc, + writeConcernToUse); + handleAnyWriteResultErrors(writeResult, dbDoc, MongoActionOperation.SAVE); + return dbDoc.get(ID_FIELD); } }); } @@ -949,29 +923,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { entity); 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); } - WriteResult wr; MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.UPDATE, collectionName, entityClass, updateObj, queryObj); WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction); - if (writeConcernToUse == null) { - wr = collection.update(queryObj, updateObj, upsert, multi); - } else { - wr = collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse); - } + WriteResult writeResult = writeConcernToUse == null ? collection.update(queryObj, updateObj, upsert, multi) + : collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse); if (entity != null && entity.hasVersionProperty() && !multi) { - if (wr.getN() == 0) { + if (writeResult.getN() == 0) { throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: " + updateObj.toMap().toString()); } } - handleAnyWriteResultErrors(wr, queryObj, "update with '" + updateObj + "'"); - return wr; + handleAnyWriteResultErrors(writeResult, queryObj, MongoActionOperation.UPDATE); + return writeResult; } }); } @@ -1045,27 +1015,30 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } protected void doRemove(final String collectionName, final Query query, final Class entityClass) { + if (query == 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 { + DBObject dboq = mapper.getMappedObject(queryObject, entity); - WriteResult wr = null; + MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.REMOVE, collectionName, entityClass, null, queryObject); WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction); + if (LOGGER.isDebugEnabled()) { - LOGGER.debug("remove using query: " + dboq + " in collection: " + collection.getName()); + LOGGER.debug("Remove using query: {} in collection: {}.", new Object[] { dboq, collection.getName() }); } - if (writeConcernToUse == null) { - wr = collection.remove(dboq); - } else { - wr = collection.remove(dboq, writeConcernToUse); - } - handleAnyWriteResultErrors(wr, dboq, "remove"); + + WriteResult wr = writeConcernToUse == null ? collection.remove(dboq) : collection.remove(dboq, + writeConcernToUse); + handleAnyWriteResultErrors(wr, dboq, MongoActionOperation.REMOVE); return null; } }); @@ -1122,7 +1095,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { handleCommandError(commandResult, commandObject); if (LOGGER.isDebugEnabled()) { - LOGGER.debug(String.format("MapReduce command result = [%s]", serializeToJsonSafely(commandObject))); + LOGGER.debug("MapReduce command result = [{}]", serializeToJsonSafely(commandObject)); } MapReduceOutput mapReduceOutput = new MapReduceOutput(inputCollection, commandObject, commandResult); @@ -1175,14 +1148,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { DBObject commandObject = new BasicDBObject("group", dbo); if (LOGGER.isDebugEnabled()) { - LOGGER.debug(String.format("Executing Group with DBObject [%s]", serializeToJsonSafely(commandObject))); + LOGGER.debug("Executing Group with DBObject [{}]", serializeToJsonSafely(commandObject)); } CommandResult commandResult = executeCommand(commandObject, getDb().getOptions()); handleCommandError(commandResult, commandObject); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Group command result = [" + commandResult + "]"); + LOGGER.debug("Group command result = [{}]", commandResult); } @SuppressWarnings("unchecked") @@ -1298,7 +1271,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { 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; } @@ -1326,14 +1299,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * 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 query document is specified as a standard DBObject and so is the fields specification. - *

- * Can be overridden by subclasses. + * 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 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 @@ -1364,9 +1333,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * 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. + * 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. * * @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 @@ -1465,7 +1433,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { if (savedObject instanceof BasicDBObject) { DBObject dbObject = (DBObject) savedObject; - dbObject.put(ID, id); + dbObject.put(ID_FIELD, id); return; } @@ -1614,37 +1582,45 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } /** - * Checks and handles any errors. - *

- * Current implementation logs errors. Future version may make this configurable to log warning, errors or throw - * exception. + * Handles {@link WriteResult} errors based on the configured {@link WriteResultChecking}. + * + * @param writeResult + * @param query + * @param operation */ - protected void handleAnyWriteResultErrors(WriteResult wr, DBObject query, String operation) { + protected void handleAnyWriteResultErrors(WriteResult writeResult, DBObject query, MongoActionOperation operation) { - if (WriteResultChecking.NONE == this.writeResultChecking) { + if (writeResultChecking == WriteResultChecking.NONE) { return; } - String error = wr.getError(); + String error = writeResult.getError(); - if (error != null) { - String message; - if (operation.equals("insert") || operation.equals("save")) { - // assuming the insert operations will begin with insert string + if (error == null) { + return; + } + + String message; + + switch (operation) { + + case INSERT: + case SAVE: message = String.format("Insert/Save for %s failed: %s", query, error); - } else if (operation.equals("insert_list")) { + break; + case INSERT_LIST: message = String.format("Insert list failed: %s", error); - } else { + break; + default: message = String.format("Execution of %s%s failed: %s", operation, - query == null ? "" : "' using '" + query.toString() + "' query", error); - } + query == null ? "" : " using query " + query.toString(), error); + } - if (WriteResultChecking.EXCEPTION == this.writeResultChecking) { - throw new DataIntegrityViolationException(message); - } else { - LOGGER.error(message); - return; - } + if (writeResultChecking == WriteResultChecking.EXCEPTION) { + throw new DataIntegrityViolationException(message); + } else { + LOGGER.error(message); + return; } } @@ -1732,7 +1708,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { private static class FindCallback implements CollectionCallback { private final DBObject query; - private final DBObject fields; public FindCallback(DBObject query) { @@ -1840,12 +1815,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { } } - private class DefaultWriteConcernResolver implements WriteConcernResolver { + private enum DefaultWriteConcernResolver implements WriteConcernResolver { + + INSTANCE; public WriteConcern resolve(MongoAction action) { return action.getDefaultWriteConcern(); } - } class QueryCursorPreparer implements CursorPreparer { @@ -1909,7 +1885,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { * Creates a new {@link GeoNearResultDbObjectCallback} using the given {@link DbObjectCallback} delegate for * {@link GeoResult} content unmarshalling. * - * @param delegate + * @param delegate must not be {@literal null}. */ public GeoNearResultDbObjectCallback(DbObjectCallback delegate, Metric metric) { Assert.notNull(delegate); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java index d85083cfd..e5a1a46a9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/SimpleMongoDbFactory.java @@ -47,7 +47,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { * Create an instance of {@link SimpleMongoDbFactory} given the {@link Mongo} instance and database name. * * @param mongo Mongo instance, must not be {@literal null}. - * @param databaseName database name, not be {@literal null}. + * @param databaseName database name, not be {@literal null} or empty. */ public SimpleMongoDbFactory(Mongo mongo, String databaseName) { this(mongo, databaseName, UserCredentials.NO_CREDENTIALS, false); @@ -57,7 +57,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory { * Create an instance of SimpleMongoDbFactory given the Mongo instance, database name, and username/password * * @param mongo Mongo instance, must not be {@literal null}. - * @param databaseName Database name, must not be {@literal null}. + * @param databaseName Database name, must not be {@literal null} or empty. * @param credentials username and password. */ public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java index 104cd2905..fa3858237 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteConcernResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2011-2012 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. @@ -13,27 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.mongodb.core; import com.mongodb.WriteConcern; /** - * A strategy interface to determine the WriteConcern to use for a given MongoDbAction. - * - * Return the passed in default WriteConcern (a property on MongoAction) if no determination can be made. + * A strategy interface to determine the {@link WriteConcern} to use for a given {@link MongoAction}. Return the passed + * in default {@link WriteConcern} (a property on {@link MongoAction}) if no determination can be made. * * @author Mark Pollack - * + * @author Oliver Gierke */ public interface WriteConcernResolver { /** - * Resolve the WriteConcern given the MongoAction + * Resolve the {@link WriteConcern} given the {@link MongoAction}. * - * @param action describes the context of the Mongo action. Contains a default WriteConcern to use if one should not - * be resolved. - * @return a WriteConcern based on the passed in MongoAction value, maybe null + * @param action describes the context of the Mongo action. Contains a default {@link WriteConcern} to use if one + * should not be resolved. + * @return a {@link WriteConcern} based on the passed in {@link MongoAction} value, maybe {@literal null}. */ WriteConcern resolve(MongoAction action); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteResultChecking.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteResultChecking.java index 70015abe5..9d4e4b5b3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteResultChecking.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/WriteResultChecking.java @@ -1,5 +1,28 @@ +/* + * Copyright 2012 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.mongodb.core; +/** + * Enum to represent how strict the check of {@link com.mongodb.WriteResult} shall be. It can either be skipped entirely + * (use {@link #NONE}), or errors can be logged ({@link #LOG}) or cause an exception to be thrown {@link #EXCEPTION}. + * + * @author Thomas Risberg + * @author Oliver Gierke + */ public enum WriteResultChecking { + NONE, LOG, EXCEPTION } 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 68d4b8de4..244d711d1 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 @@ -212,19 +212,14 @@ public class MongoTemplateTests { template.insert(person); - try { + thrown.expect(DataIntegrityViolationException.class); + thrown.expectMessage("Execution"); + thrown.expectMessage("$push"); + thrown.expectMessage("firstName"); - Query query = new Query(Criteria.where("firstName").is("Amol")); - Update upd = new Update().push("age", 29); - template.updateFirst(query, upd, Person.class); - fail("Expected DataIntegrityViolationException!"); - - } catch (DataIntegrityViolationException e) { - - assertThat(e.getMessage(), - is("Execution of update with '{ \"$push\" : { \"age\" : 29}}'' using '{ \"firstName\" : \"Amol\"}' " - + "query failed: Cannot apply $push/$pushAll modifier to non-array")); - } + Query query = new Query(Criteria.where("firstName").is("Amol")); + Update upd = new Update().push("age", 29); + template.updateFirst(query, upd, Person.class); } /** @@ -1028,7 +1023,7 @@ public class MongoTemplateTests { assertThat(lastMongoAction.getCollectionName(), is("personWithIdPropertyOfTypeObjectId")); assertThat(lastMongoAction.getDefaultWriteConcern(), equalTo(WriteConcern.NONE)); assertThat(lastMongoAction.getDocument(), notNullValue()); - assertThat(lastMongoAction.getEntityClass().toString(), is(PersonWithIdPropertyOfTypeObjectId.class.toString())); + assertThat(lastMongoAction.getEntityType().toString(), is(PersonWithIdPropertyOfTypeObjectId.class.toString())); assertThat(lastMongoAction.getMongoActionOperation(), is(MongoActionOperation.UPDATE)); assertThat(lastMongoAction.getQuery(), equalTo(q.getQueryObject()));