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 645def72a..c056517e7 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
@@ -769,8 +769,8 @@ public interface MongoOperations extends FluentMongoOperations {
}
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
+ * Triggers findAndModify
+ * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification. Must not be {@literal null}.
@@ -782,8 +782,8 @@ public interface MongoOperations extends FluentMongoOperations {
T findAndModify(Query query, Update update, Class entityClass);
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
+ * Triggers findAndModify
+ * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification. Must not be {@literal null}.
@@ -796,8 +796,8 @@ public interface MongoOperations extends FluentMongoOperations {
T findAndModify(Query query, Update update, Class entityClass, String collectionName);
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
+ * Triggers findAndModify
+ * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
@@ -813,8 +813,8 @@ public interface MongoOperations extends FluentMongoOperations {
T findAndModify(Query query, Update update, FindAndModifyOptions options, Class entityClass);
/**
- * Triggers findAndModify
- * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
+ * Triggers findAndModify
+ * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
@@ -1142,6 +1142,7 @@ public interface MongoOperations extends FluentMongoOperations {
* @param query the query document that specifies the criteria used to remove a record.
* @param entityClass class that determines the collection to use.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
+ * @throws IllegalArgumentException when {@literal query} or {@literal entityClass} is {@literal null}.
*/
DeleteResult remove(Query query, Class> entityClass);
@@ -1153,6 +1154,8 @@ public interface MongoOperations extends FluentMongoOperations {
* @param entityClass class of the pojo to be operated on. Can be {@literal null}.
* @param collectionName name of the collection where the objects will removed, must not be {@literal null} or empty.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
+ * @throws IllegalArgumentException when {@literal query}, {@literal entityClass} or {@literal collectionName} is
+ * {@literal null}.
*/
DeleteResult remove(Query query, Class> entityClass, String collectionName);
@@ -1165,6 +1168,7 @@ public interface MongoOperations extends FluentMongoOperations {
* @param query the query document that specifies the criteria used to remove a record.
* @param collectionName name of the collection where the objects will removed, must not be {@literal null} or empty.
* @return the {@link DeleteResult} which lets you access the results of the previous delete.
+ * @throws IllegalArgumentException when {@literal query} or {@literal collectionName} is {@literal null}.
*/
DeleteResult remove(Query query, String collectionName);
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 4bf66064d..8362a1341 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
@@ -24,19 +24,8 @@ import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Scanner;
-import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -135,6 +124,7 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
+import com.mongodb.Cursor;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.Mongo;
@@ -1693,13 +1683,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
protected DeleteResult doRemove(final String collectionName, final Query query,
@Nullable final Class entityClass) {
+ Assert.notNull(query, "Query must not be null!");
Assert.hasText(collectionName, "Collection name must not be null or empty!");
- if (query == null) {
- throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null!");
- }
- final Document queryObject = query.getQueryObject();
final MongoPersistentEntity> entity = getPersistentEntity(entityClass);
+ final Document queryObject = queryMapper.getMappedObject(query.getQueryObject(), entity);
return execute(collectionName, new CollectionCallback() {
@@ -1708,7 +1696,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
maybeEmitEvent(new BeforeDeleteEvent(queryObject, entityClass, collectionName));
- Document mappedQuery = queryMapper.getMappedObject(queryObject, entity);
+ Document removeQuery = queryObject;
DeleteOptions options = new DeleteOptions();
query.getCollation().map(Collation::toMongoCollation).ifPresent(options::collation);
@@ -1721,13 +1709,26 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
DeleteResult dr = null;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Remove using query: {} in collection: {}.",
- new Object[] { serializeToJsonSafely(mappedQuery), collectionName });
+ new Object[] { serializeToJsonSafely(removeQuery), collectionName });
+ }
+
+ if (query.getLimit() > 0 || query.getSkip() > 0) {
+
+ MongoCursor cursor = new QueryCursorPreparer(query, entityClass)
+ .prepare(collection.find(removeQuery).projection(new Document(ID_FIELD, 1))).iterator();
+
+ Set