diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java
index a470db656..659820946 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/CursorPreparer.java
@@ -22,7 +22,7 @@ import com.mongodb.DBCursor;
*
* @author Oliver Gierke
*/
-public interface CursorPreparer {
+interface CursorPreparer {
/**
* Prepare the given cursor (apply limits, skips and so on). Returns th eprepared cursor.
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 a13ef6350..d670b1499 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
@@ -91,18 +91,6 @@ public interface MongoOperations {
*/
void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch);
- /**
- * Execute a MongoDB query and iterate over the query results on a per-document basis with a DocumentCallbackHandler using the
- * provided CursorPreparer.
- * @param query the query class that specifies the criteria used to find a record and also an optional fields
- * specification
- * @param collectionName name of the collection to retrieve the objects from
- * @param dch the handler that will extract results, one document at a time
- * @param preparer allows for customization of the DBCursor used when iterating over the result set, (apply limits,
- * skips and so on).
- */
- void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch, CursorPreparer preparer);
-
/**
* Executes a {@link DbCallback} translating any exceptions as necessary.
*
@@ -271,7 +259,7 @@ public interface MongoOperations {
/**
- * Execute a group operation over the entire collection.
+ * Execute a group operation over the entire collection.
* The group operation entity class should match the 'shape' of the returned object that takes int account the
* initial document structure as well as any finalize functions.
*
@@ -281,7 +269,7 @@ public interface MongoOperations {
* @param entityClass The parameterized type of the returned list
* @return The results of the group operation
*/
- GroupByResults group(String inputCollectionName, GroupBy groupBy, Class entityClass);
+ GroupByResults group(String inputCollectionName, GroupBy groupBy, Class entityClass);
/**
* Execute a group operation restricting the rows to those which match the provided Criteria.
@@ -452,26 +440,6 @@ public interface MongoOperations {
*/
List find(Query query, Class entityClass, String collectionName);
- /**
- * Map the results of an ad-hoc query on the specified 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 is specified as a {@link Query} which can be created either using the {@link BasicQuery} or the more
- * feature rich {@link Query}.
- *
- * @param query the query class that specifies the criteria used to find a record and also an optional fields
- * specification
- * @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
- *
- * @return the List of converted objects.
- */
- List find(Query query, Class entityClass, CursorPreparer preparer, String collectionName);
-
/**
* Returns a document with the given id mapped onto the given class. The collection the query is ran against will be
* derived from the given target class as well.
@@ -647,7 +615,7 @@ public interface MongoOperations {
void save(Object objectToSave, String collectionName);
/**
- * Performs an upsert. If no document is found that matches the query, a new document is created and inserted
+ * Performs an upsert. If no document is found that matches the query, a new document is created and inserted
* by combining the query document and the update document.
*
* @param query the query document that specifies the criteria used to select a record to be upserted
@@ -659,7 +627,7 @@ public interface MongoOperations {
/**
- * Performs an upsert. If no document is found that matches the query, a new document is created and inserted
+ * Performs an upsert. If no document is found that matches the query, a new document is created and inserted
* by combining the query document and the update document.
*
* @param query the query document that specifies the criteria used to select a record to be updated
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 f7cc8d579..eaabab3d5 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
@@ -2,6 +2,8 @@
* Copyright 2010-2011 the original author or authors.
*
* Licensed under t
+import org.springframework.util.ResourceUtils;
+
import org.springframework.data.convert.EntityReader;
he Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -125,7 +127,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* the DB or Collection.
*/
private WriteConcern writeConcern = null;
-
+
private WriteConcernResolver writeConcernResolver = new DefaultWriteConcernResolver();
/*
@@ -135,7 +137,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
private WriteResultChecking writeResultChecking = WriteResultChecking.NONE;
/**
- * Set the ReadPreference when operating on a collection. See {@link #prepareCollection(DBCollection)}
+ * Set the ReadPreference when operating on a collection. See {@link #prepareCollection(DBCollection)}
*/
private ReadPreference readPreference = null;
@@ -187,11 +189,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* @param mongoConverter
*/
public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) {
+
Assert.notNull(mongoDbFactory);
this.mongoDbFactory = mongoDbFactory;
this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter(mongoDbFactory) : mongoConverter;
- this.mapper = new QueryMapper(this.mongoConverter.getConversionService());
+ 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();
@@ -233,9 +236,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
public void setWriteConcernResolver(WriteConcernResolver writeConcernResolver) {
this.writeConcernResolver = writeConcernResolver;
}
-
+
/**
- * Used by @{link {@link #prepareCollection(DBCollection)} to set the {@link ReadPreference} before any operations are performed.
+ * Used by @{link {@link #prepareCollection(DBCollection)} to set the {@link ReadPreference} before any operations are
+ * performed.
+ *
* @param readPreference
*/
public void setReadPreference(ReadPreference readPreference) {
@@ -307,16 +312,32 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
}
public void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch) {
- executeQuery(query, collectionName, dch, null);
+ executeQuery(query, collectionName, dch, new QueryCursorPreparer(query));
}
- public void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch, CursorPreparer preparer) {
+ /**
+ * Execute a MongoDB query and iterate over the query results on a per-document basis with a
+ * {@link DocumentCallbackHandler} using the provided CursorPreparer.
+ *
+ * @param query the query class that specifies the criteria used to find a record and also an optional fields
+ * specification, must not be {@literal null}.
+ * @param collectionName name of the collection to retrieve the objects from
+ * @param dch the handler that will extract results, one document at a time
+ * @param preparer allows for customization of the {@link DBCursor} used when iterating over the result set, (apply
+ * limits, skips and so on).
+ */
+ protected void executeQuery(Query query, String collectionName, DocumentCallbackHandler dch, CursorPreparer preparer) {
+
+ Assert.notNull(query);
+
DBObject queryObject = query.getQueryObject();
DBObject fieldsObject = query.getFieldsObject();
+
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("find using query: " + queryObject + " fields: " + fieldsObject + " in collection: "
+ collectionName);
}
+
this.executeQueryInternal(new FindCallback(queryObject, fieldsObject), preparer, dch, collectionName);
}
@@ -456,36 +477,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
}
public List find(final Query query, Class entityClass, String collectionName) {
- CursorPreparer cursorPreparer = null;
- if (query.getSkip() > 0 || query.getLimit() > 0 || query.getSortObject() != null) {
- cursorPreparer = new CursorPreparer() {
-
- public DBCursor prepare(DBCursor cursor) {
- DBCursor cursorToUse = cursor;
- try {
- if (query.getSkip() > 0) {
- cursorToUse = cursorToUse.skip(query.getSkip());
- }
- if (query.getLimit() > 0) {
- cursorToUse = cursorToUse.limit(query.getLimit());
- }
- if (query.getSortObject() != null) {
- cursorToUse = cursorToUse.sort(query.getSortObject());
- }
- } catch (RuntimeException e) {
- throw potentiallyConvertRuntimeException(e);
- }
- return cursorToUse;
- }
- };
- }
+ CursorPreparer cursorPreparer = query == null ? null : new QueryCursorPreparer(query);
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 T findById(Object id, Class entityClass) {
MongoPersistentEntity> persistentEntity = mappingContext.getPersistentEntity(entityClass);
return findById(id, entityClass, persistentEntity.getCollection());
@@ -542,7 +537,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return doFindAndModify(collectionName, query.getQueryObject(), query.getFieldsObject(), query.getSortObject(),
entityClass, update, options);
}
-
+
// 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.
@@ -563,13 +558,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
public long count(final Query query, String collectionName) {
return count(query, null, collectionName);
}
-
+
private long count(Query query, Class> entityClass, String collectionName) {
-
+
Assert.hasText(collectionName);
final DBObject dbObject = query == null ? null : mapper.getMappedObject(query.getQueryObject(),
entityClass == null ? null : mappingContext.getPersistentEntity(entityClass));
-
+
return execute(collectionName, new CollectionCallback() {
public Long doInCollection(DBCollection collection) throws MongoException, DataAccessException {
return collection.count(dbObject);
@@ -729,7 +724,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
}
return execute(collectionName, new CollectionCallback