diff --git a/pom.xml b/pom.xml
index 50a3505945..6c52fce9ae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,9 +28,10 @@
multi
spring-data-mongodb
- 2.0.0.BUILD-SNAPSHOT
+ 2.0.0.DATACMNS-867-SNAPSHOT
3.2.2
1.2.0
+ 2.2.17
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 4fd204dfc1..d21d05389a 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
@@ -17,6 +17,7 @@
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
+import static org.springframework.data.util.Optionals.*;
import java.io.IOException;
import java.util.ArrayList;
@@ -29,11 +30,11 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import com.mongodb.*;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
@@ -104,6 +105,8 @@
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.data.util.CloseableIterator;
+import org.springframework.data.util.Optionals;
+import org.springframework.data.util.Pair;
import org.springframework.jca.cci.core.ConnectionCallback;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -111,6 +114,15 @@
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
+import com.mongodb.CommandResult;
+import com.mongodb.Cursor;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.Mongo;
+import com.mongodb.MongoException;
+import com.mongodb.ReadPreference;
+import com.mongodb.WriteConcern;
+import com.mongodb.WriteResult;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MapReduceIterable;
import com.mongodb.client.MongoCollection;
@@ -353,7 +365,7 @@ public CloseableIterator stream(final Query query, final Class entityT
public CloseableIterator doInCollection(MongoCollection collection)
throws MongoException, DataAccessException {
- MongoPersistentEntity> persistentEntity = mappingContext.getPersistentEntity(entityType);
+ MongoPersistentEntity> persistentEntity = mappingContext.getRequiredPersistentEntity(entityType);
Document mappedFields = queryMapper.getMappedFields(query.getFieldsObject(), persistentEntity);
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), persistentEntity);
@@ -361,8 +373,7 @@ public CloseableIterator doInCollection(MongoCollection collection)
FindIterable cursor = collection.find(mappedQuery).projection(mappedFields);
QueryCursorPreparer cursorPreparer = new QueryCursorPreparer(query, entityType);
- ReadDocumentCallback readCallback = new ReadDocumentCallback(mongoConverter, entityType,
- collectionName);
+ ReadDocumentCallback readCallback = new ReadDocumentCallback(mongoConverter, entityType, collectionName);
return new CloseableIterableCursorAdapter(cursorPreparer.prepare(cursor), exceptionTranslator, readCallback);
}
@@ -440,7 +451,7 @@ protected void executeQuery(Query query, String collectionName, DocumentCallback
Assert.notNull(query);
- Document queryObject = queryMapper.getMappedObject(query.getQueryObject(), null);
+ Document queryObject = queryMapper.getMappedObject(query.getQueryObject(), Optional.empty());
Document sortObject = query.getSortObject();
Document fieldsObject = query.getFieldsObject();
@@ -632,9 +643,11 @@ public T findById(Object id, Class entityClass) {
}
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_FIELD : idProperty.getName();
+
+ String idKey = mappingContext.getPersistentEntity(entityClass)//
+ .flatMap(it -> it.getIdProperty())//
+ .map(it -> it.getName()).orElse(ID_FIELD);
+
return doFindOne(collectionName, new Document(idKey, id), null, entityClass);
}
@@ -752,13 +765,9 @@ public long count(Query query, Class> entityClass, String collectionName) {
Assert.hasText(collectionName);
final Document document = query == null ? null
: queryMapper.getMappedObject(query.getQueryObject(),
- entityClass == null ? null : mappingContext.getPersistentEntity(entityClass));
+ Optional.ofNullable(entityClass).flatMap(it -> mappingContext.getPersistentEntity(entityClass)));
- return execute(collectionName, new CollectionCallback() {
- public Long doInCollection(MongoCollection collection) throws MongoException, DataAccessException {
- return collection.count(document);
- }
- });
+ return execute(collectionName, (CollectionCallback) collection -> collection.count(document));
}
/*
@@ -877,13 +886,13 @@ private Document toDocument(T objectToSave, MongoWriter writer) {
private void initializeVersionProperty(Object entity) {
- MongoPersistentEntity> mongoPersistentEntity = getPersistentEntity(entity.getClass());
+ Optional extends MongoPersistentEntity>> persistentEntity = getPersistentEntity(entity.getClass());
- if (mongoPersistentEntity != null && mongoPersistentEntity.hasVersionProperty()) {
- ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(
- mongoPersistentEntity.getPropertyAccessor(entity), mongoConverter.getConversionService());
- accessor.setProperty(mongoPersistentEntity.getVersionProperty(), 0);
- }
+ ifAllPresent(persistentEntity, persistentEntity.flatMap(it -> it.getVersionProperty()), (l, r) -> {
+ ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(l.getPropertyAccessor(entity),
+ mongoConverter.getConversionService());
+ accessor.setProperty(r, Optional.of(0));
+ });
}
public void insert(Collection extends Object> batchToSave, Class> entityClass) {
@@ -908,11 +917,7 @@ protected void doInsertAll(Collection extends T> listToSave, MongoWriter entity = mappingContext.getPersistentEntity(element.getClass());
-
- if (entity == null) {
- throw new InvalidDataAccessApiUsageException("No PersistentEntity information found for " + element.getClass());
- }
+ MongoPersistentEntity> entity = mappingContext.getRequiredPersistentEntity(element.getClass());
String collection = entity.getCollection();
List collectionElements = elementsByCollection.get(collection);
@@ -969,41 +974,35 @@ public void save(Object objectToSave, String collectionName) {
Assert.notNull(objectToSave);
Assert.hasText(collectionName);
- MongoPersistentEntity> mongoPersistentEntity = getPersistentEntity(objectToSave.getClass());
-
- // No optimistic locking -> simple save
- if (mongoPersistentEntity == null || !mongoPersistentEntity.hasVersionProperty()) {
- doSave(collectionName, objectToSave, this.mongoConverter);
- return;
- }
+ Optional extends MongoPersistentEntity>> entity = getPersistentEntity(objectToSave.getClass());
+ Optional versionProperty = entity.flatMap(it -> it.getVersionProperty());
- doSaveVersioned(objectToSave, mongoPersistentEntity, collectionName);
+ mapIfAllPresent(entity, versionProperty, //
+ (l, r) -> doSaveVersioned(objectToSave, l, collectionName))//
+ .orElseGet(() -> doSave(collectionName, objectToSave, this.mongoConverter));
}
- private void doSaveVersioned(T objectToSave, MongoPersistentEntity> entity, String collectionName) {
+ private T doSaveVersioned(T objectToSave, MongoPersistentEntity> entity, String collectionName) {
ConvertingPropertyAccessor convertingAccessor = new ConvertingPropertyAccessor(
entity.getPropertyAccessor(objectToSave), mongoConverter.getConversionService());
- MongoPersistentProperty idProperty = entity.getIdProperty();
- MongoPersistentProperty versionProperty = entity.getVersionProperty();
+ Optional versionProperty = entity.getVersionProperty();
+ Optional versionNumber = versionProperty.flatMap(it -> convertingAccessor.getProperty(it, Number.class));
- Object version = convertingAccessor.getProperty(versionProperty);
- Number versionNumber = convertingAccessor.getProperty(versionProperty, Number.class);
+ return mapIfAllPresent(versionProperty, versionNumber, (property, number) -> {
- // Fresh instance -> initialize version property
- if (version == null) {
- doInsert(collectionName, objectToSave, this.mongoConverter);
- } else {
+ MongoPersistentProperty idProperty = entity.getIdProperty()//
+ .orElseThrow(() -> new MappingException("Couldn't find identifier property on entity " + entity + "!"));
assertUpdateableIdIfNotSet(objectToSave);
// Create query for entity with the id and old version
Object id = convertingAccessor.getProperty(idProperty);
- Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(versionProperty.getName()).is(version));
+ Query query = Query.query(Criteria.where(idProperty.getName()).is(id).and(property.getName()).is(number));
// Bump version number
- convertingAccessor.setProperty(versionProperty, versionNumber.longValue() + 1);
+ convertingAccessor.setProperty(property, Optional.of(number.longValue() + 1));
Document document = new Document();
@@ -1021,10 +1020,16 @@ private void doSaveVersioned(T objectToSave, MongoPersistentEntity> entity
versionNumber, collectionName));
}
maybeEmitEvent(new AfterSaveEvent(objectToSave, document, collectionName));
- }
+
+ return objectToSave;
+
+ }).orElseGet(() -> {
+ doInsert(collectionName, objectToSave, this.mongoConverter);
+ return objectToSave;
+ });
}
- protected void doSave(String collectionName, T objectToSave, MongoWriter writer) {
+ protected T doSave(String collectionName, T objectToSave, MongoWriter writer) {
assertUpdateableIdIfNotSet(objectToSave);
@@ -1037,6 +1042,8 @@ protected void doSave(String collectionName, T objectToSave, MongoWriter
populateIdIfNecessary(objectToSave, id);
maybeEmitEvent(new AfterSaveEvent(objectToSave, dbDoc, collectionName));
+
+ return objectToSave;
}
protected Object insertDocument(final String collectionName, final Document document, final Class> entityClass) {
@@ -1174,7 +1181,8 @@ protected UpdateResult doUpdate(final String collectionName, final Query query,
public UpdateResult doInCollection(MongoCollection collection)
throws MongoException, DataAccessException {
- MongoPersistentEntity> entity = entityClass == null ? null : getPersistentEntity(entityClass);
+ Optional extends MongoPersistentEntity>> entity = entityClass == null ? null
+ : getPersistentEntity(entityClass);
increaseVersionForUpdateIfNecessary(entity, update);
@@ -1210,23 +1218,23 @@ public UpdateResult doInCollection(MongoCollection collection)
});
}
- private void increaseVersionForUpdateIfNecessary(MongoPersistentEntity> persistentEntity, Update update) {
+ private void increaseVersionForUpdateIfNecessary(Optional extends MongoPersistentEntity>> persistentEntity,
+ Update update) {
- if (persistentEntity != null && persistentEntity.hasVersionProperty()) {
- String versionFieldName = persistentEntity.getVersionProperty().getFieldName();
+ ifAllPresent(persistentEntity, persistentEntity.flatMap(it -> it.getVersionProperty()), (entity, property) -> {
+ String versionFieldName = property.getFieldName();
if (!update.modifies(versionFieldName)) {
update.inc(versionFieldName, 1L);
}
- }
+ });
}
- private boolean documentContainsVersionProperty(Document document, MongoPersistentEntity> persistentEntity) {
+ private boolean documentContainsVersionProperty(Document document,
+ Optional extends MongoPersistentEntity>> persistentEntity) {
- if (persistentEntity == null || !persistentEntity.hasVersionProperty()) {
- return false;
- }
-
- return document.containsKey(persistentEntity.getVersionProperty().getFieldName());
+ return mapIfAllPresent(persistentEntity, persistentEntity.flatMap(it -> it.getVersionProperty()), //
+ (entity, property) -> document.containsKey(property.getFieldName()))//
+ .orElse(false);
}
public DeleteResult remove(Object object) {
@@ -1256,25 +1264,21 @@ public DeleteResult remove(Object object, String collection) {
* @param object
* @return
*/
- private Entry extractIdPropertyAndValue(Object object) {
+ private Pair> extractIdPropertyAndValue(Object object) {
Assert.notNull(object, "Id cannot be extracted from 'null'.");
Class> objectType = object.getClass();
if (object instanceof Document) {
- return Collections.singletonMap(ID_FIELD, ((Document) object).get(ID_FIELD)).entrySet().iterator().next();
+ return Pair.of(ID_FIELD, Optional.ofNullable(((Document) object).get(ID_FIELD)));
}
- MongoPersistentEntity> entity = mappingContext.getPersistentEntity(objectType);
- MongoPersistentProperty idProp = entity == null ? null : entity.getIdProperty();
-
- if (idProp == null || entity == null) {
- throw new MappingException("No id property found for object of type " + objectType);
- }
+ Optional extends MongoPersistentEntity>> entity = mappingContext.getPersistentEntity(objectType);
- Object idValue = entity.getPropertyAccessor(object).getProperty(idProp);
- return Collections.singletonMap(idProp.getFieldName(), idValue).entrySet().iterator().next();
+ return mapIfAllPresent(entity, entity.flatMap(it -> it.getIdProperty()), //
+ (l, r) -> Pair.of(r.getFieldName(), l.getPropertyAccessor(object).getProperty(r)))//
+ .orElseThrow(() -> new MappingException("No id property found for object of type " + objectType));
}
/**
@@ -1285,8 +1289,8 @@ private Entry extractIdPropertyAndValue(Object object) {
*/
private Query getIdQueryFor(Object object) {
- Entry id = extractIdPropertyAndValue(object);
- return new Query(where(id.getKey()).is(id.getValue()));
+ Pair> id = extractIdPropertyAndValue(object);
+ return new Query(where(id.getFirst()).is(id.getSecond().orElse(null)));
}
/**
@@ -1300,34 +1304,38 @@ private Query getIdInQueryFor(Collection> objects) {
Assert.notEmpty(objects, "Cannot create Query for empty collection.");
Iterator> it = objects.iterator();
- Entry firstEntry = extractIdPropertyAndValue(it.next());
+ Pair> pair = extractIdPropertyAndValue(it.next());
ArrayList