Browse Source

DATAMONGO-1992 - Add mutation support for immutable objects through MongoTemplate and SimpleMongoRepository.

Persisting methods of MongoTemplate and SimpleMongoRepository now return potentially new object instances of immutable objects. New instances are created using wither methods/Kotlin copy(…) methods if an immutable object requires association with an Id or the version number needs to be incremented.
pull/587/merge
Mark Paluch 8 years ago committed by Oliver Gierke
parent
commit
d1dea13c32
  1. 6
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperation.java
  2. 8
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperationSupport.java
  3. 21
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
  4. 142
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  5. 19
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java
  6. 29
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

6
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperation.java

@ -63,17 +63,19 @@ public interface ExecutableInsertOperation { @@ -63,17 +63,19 @@ public interface ExecutableInsertOperation {
* Insert exactly one object.
*
* @param object must not be {@literal null}.
* @return the inserted object.
* @throws IllegalArgumentException if object is {@literal null}.
*/
void one(T object);
T one(T object);
/**
* Insert a collection of objects.
*
* @param objects must not be {@literal null}.
* @return the inserted objects.
* @throws IllegalArgumentException if objects is {@literal null}.
*/
void all(Collection<? extends T> objects);
Collection<? extends T> all(Collection<? extends T> objects);
}
/**

8
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableInsertOperationSupport.java

@ -72,11 +72,11 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation { @@ -72,11 +72,11 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation.TerminatingInsert#insert(java.lang.Class)
*/
@Override
public void one(T object) {
public T one(T object) {
Assert.notNull(object, "Object must not be null!");
template.insert(object, getCollectionName());
return template.insert(object, getCollectionName());
}
/*
@ -84,11 +84,11 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation { @@ -84,11 +84,11 @@ class ExecutableInsertOperationSupport implements ExecutableInsertOperation {
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation.TerminatingInsert#all(java.util.Collection)
*/
@Override
public void all(Collection<? extends T> objects) {
public Collection<T> all(Collection<? extends T> objects) {
Assert.notNull(objects, "Objects must not be null!");
template.insert(objects, getCollectionName());
return template.insert(objects, getCollectionName());
}
/*

21
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java

@ -1141,8 +1141,9 @@ public interface MongoOperations extends FluentMongoOperations { @@ -1141,8 +1141,9 @@ public interface MongoOperations extends FluentMongoOperations {
* Insert is used to initially store the object into the database. To update an existing object use the save method.
*
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the inserted object.
*/
void insert(Object objectToSave);
<T> T insert(T objectToSave);
/**
* Insert the object into the specified collection.
@ -1154,32 +1155,36 @@ public interface MongoOperations extends FluentMongoOperations { @@ -1154,32 +1155,36 @@ public interface MongoOperations extends FluentMongoOperations {
*
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
* @return the inserted object.
*/
void insert(Object objectToSave, String collectionName);
<T> T insert(T objectToSave, String collectionName);
/**
* Insert a Collection of objects into a collection in a single batch write to the database.
*
* @param batchToSave the batch of objects to save. Must not be {@literal null}.
* @param entityClass class that determines the collection to use. Must not be {@literal null}.
* @return the inserted objects that.
*/
void insert(Collection<? extends Object> batchToSave, Class<?> entityClass);
<T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass);
/**
* Insert a batch of objects into the specified collection in a single batch write to the database.
*
* @param batchToSave the list of objects to save. Must not be {@literal null}.
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
* @return the inserted objects that.
*/
void insert(Collection<? extends Object> batchToSave, String collectionName);
<T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName);
/**
* Insert a mixed Collection of objects into a database collection determining the collection name to use based on the
* class.
*
* @param objectsToSave the list of objects to save. Must not be {@literal null}.
* @return the inserted objects.
*/
void insertAll(Collection<? extends Object> objectsToSave);
<T> Collection<T> insertAll(Collection<? extends T> objectsToSave);
/**
* Save the object to the collection for the entity type of the object to save. This will perform an insert if the
@ -1195,8 +1200,9 @@ public interface MongoOperations extends FluentMongoOperations { @@ -1195,8 +1200,9 @@ public interface MongoOperations extends FluentMongoOperations {
* Conversion"</a> for more details.
*
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @return the saved object.
*/
void save(Object objectToSave);
<T> T save(T objectToSave);
/**
* Save the object to the specified collection. This will perform an insert if the object is not already present, that
@ -1213,8 +1219,9 @@ public interface MongoOperations extends FluentMongoOperations { @@ -1213,8 +1219,9 @@ public interface MongoOperations extends FluentMongoOperations {
*
* @param objectToSave the object to store in the collection. Must not be {@literal null}.
* @param collectionName name of the collection to store the object in. Must not be {@literal null}.
* @return the saved object.
*/
void save(Object objectToSave, String collectionName);
<T> T save(T objectToSave, String collectionName);
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by

142
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

@ -73,16 +73,7 @@ import org.springframework.data.mongodb.core.aggregation.AggregationResults; @@ -73,16 +73,7 @@ import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.Fields;
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.JsonSchemaMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.convert.MongoJsonSchemaMapper;
import org.springframework.data.mongodb.core.convert.MongoWriter;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.convert.UpdateMapper;
import org.springframework.data.mongodb.core.convert.*;
import org.springframework.data.mongodb.core.index.IndexOperations;
import org.springframework.data.mongodb.core.index.IndexOperationsProvider;
import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher;
@ -1157,12 +1148,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1157,12 +1148,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @see org.springframework.data.mongodb.core.MongoOperations#insert(java.lang.Object)
*/
@Override
public void insert(Object objectToSave) {
public <T> T insert(T objectToSave) {
Assert.notNull(objectToSave, "ObjectToSave must not be null!");
ensureNotIterable(objectToSave);
insert(objectToSave, determineEntityCollectionName(objectToSave));
return insert(objectToSave, determineEntityCollectionName(objectToSave));
}
/*
@ -1170,13 +1161,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1170,13 +1161,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @see org.springframework.data.mongodb.core.MongoOperations#insert(java.lang.Object, java.lang.String)
*/
@Override
public void insert(Object objectToSave, String collectionName) {
public <T> T insert(T objectToSave, String collectionName) {
Assert.notNull(objectToSave, "ObjectToSave must not be null!");
Assert.notNull(collectionName, "CollectionName must not be null!");
ensureNotIterable(objectToSave);
doInsert(collectionName, objectToSave, this.mongoConverter);
return (T) doInsert(collectionName, objectToSave, this.mongoConverter);
}
protected void ensureNotIterable(@Nullable Object o) {
@ -1230,19 +1221,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1230,19 +1221,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return wc;
}
protected <T> void doInsert(String collectionName, T objectToSave, MongoWriter<T> writer) {
protected <T> T doInsert(String collectionName, T objectToSave, MongoWriter<T> writer) {
initializeVersionProperty(objectToSave);
maybeEmitEvent(new BeforeConvertEvent<>(objectToSave, collectionName));
assertUpdateableIdIfNotSet(objectToSave);
T toSave = (T) initializeVersionProperty(objectToSave);
maybeEmitEvent(new BeforeConvertEvent<>(toSave, collectionName));
assertUpdateableIdIfNotSet(toSave);
Document dbDoc = toDocument(objectToSave, writer);
Document dbDoc = toDocument(toSave, writer);
maybeEmitEvent(new BeforeSaveEvent<>(objectToSave, dbDoc, collectionName));
Object id = insertDocument(collectionName, dbDoc, objectToSave.getClass());
maybeEmitEvent(new BeforeSaveEvent<>(toSave, dbDoc, collectionName));
Object id = insertDocument(collectionName, dbDoc, toSave.getClass());
T saved = (T) populateIdIfNecessary(toSave, id);
maybeEmitEvent(new AfterSaveEvent<>(saved, dbDoc, collectionName));
populateIdIfNecessary(objectToSave, id);
maybeEmitEvent(new AfterSaveEvent<>(objectToSave, dbDoc, collectionName));
return saved;
}
/**
@ -1275,7 +1268,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1275,7 +1268,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
}
}
private void initializeVersionProperty(Object entity) {
private Object initializeVersionProperty(Object entity) {
MongoPersistentEntity<?> persistentEntity = getPersistentEntity(entity.getClass());
@ -1286,36 +1279,41 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1286,36 +1279,41 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(persistentEntity.getPropertyAccessor(entity),
mongoConverter.getConversionService());
accessor.setProperty(versionProperty, 0);
return accessor.getBean();
}
return entity;
}
@Override
public void insert(Collection<? extends Object> batchToSave, Class<?> entityClass) {
public <T> Collection<T> insert(Collection<? extends T> batchToSave, Class<?> entityClass) {
Assert.notNull(batchToSave, "BatchToSave must not be null!");
doInsertBatch(determineCollectionName(entityClass), batchToSave, this.mongoConverter);
return (Collection) doInsertBatch(determineCollectionName(entityClass), batchToSave, this.mongoConverter);
}
@Override
public void insert(Collection<? extends Object> batchToSave, String collectionName) {
public <T> Collection<T> insert(Collection<? extends T> batchToSave, String collectionName) {
Assert.notNull(batchToSave, "BatchToSave must not be null!");
Assert.notNull(collectionName, "CollectionName must not be null!");
doInsertBatch(collectionName, batchToSave, this.mongoConverter);
return (Collection) doInsertBatch(collectionName, batchToSave, this.mongoConverter);
}
@Override
public void insertAll(Collection<? extends Object> objectsToSave) {
public <T> Collection<T> insertAll(Collection<? extends T> objectsToSave) {
Assert.notNull(objectsToSave, "ObjectsToSave must not be null!");
doInsertAll(objectsToSave, this.mongoConverter);
return (Collection) doInsertAll(objectsToSave, this.mongoConverter);
}
protected <T> void doInsertAll(Collection<? extends T> listToSave, MongoWriter<T> writer) {
protected <T> Collection<T> doInsertAll(Collection<? extends T> listToSave, MongoWriter<T> writer) {
Map<String, List<T>> elementsByCollection = new HashMap<>();
List<T> savedObjects = new ArrayList<>(listToSave.size());
for (T element : listToSave) {
@ -1337,47 +1335,59 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1337,47 +1335,59 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
}
for (Map.Entry<String, List<T>> entry : elementsByCollection.entrySet()) {
doInsertBatch(entry.getKey(), entry.getValue(), this.mongoConverter);
savedObjects.addAll((Collection) doInsertBatch(entry.getKey(), entry.getValue(), this.mongoConverter));
}
return savedObjects;
}
protected <T> void doInsertBatch(String collectionName, Collection<? extends T> batchToSave, MongoWriter<T> writer) {
protected <T> Collection<T> doInsertBatch(String collectionName, Collection<? extends T> batchToSave,
MongoWriter<T> writer) {
Assert.notNull(writer, "MongoWriter must not be null!");
List<Document> documentList = new ArrayList<>();
for (T o : batchToSave) {
List<T> initializedBatchToSave = new ArrayList<>(batchToSave.size());
for (T uninitialized : batchToSave) {
initializeVersionProperty(o);
maybeEmitEvent(new BeforeConvertEvent<>(o, collectionName));
T toSave = (T) initializeVersionProperty(uninitialized);
maybeEmitEvent(new BeforeConvertEvent<>(toSave, collectionName));
Document document = toDocument(o, writer);
Document document = toDocument(toSave, writer);
maybeEmitEvent(new BeforeSaveEvent<>(o, document, collectionName));
maybeEmitEvent(new BeforeSaveEvent<>(toSave, document, collectionName));
documentList.add(document);
initializedBatchToSave.add(toSave);
}
List<Object> ids = insertDocumentList(collectionName, documentList);
List<T> savedObjects = new ArrayList<>(documentList.size());
int i = 0;
for (T obj : batchToSave) {
for (T obj : initializedBatchToSave) {
if (i < ids.size()) {
populateIdIfNecessary(obj, ids.get(i));
maybeEmitEvent(new AfterSaveEvent<>(obj, documentList.get(i), collectionName));
T saved = (T) populateIdIfNecessary(obj, ids.get(i));
maybeEmitEvent(new AfterSaveEvent<>(saved, documentList.get(i), collectionName));
savedObjects.add(saved);
} else {
savedObjects.add(obj);
}
i++;
}
return savedObjects;
}
@Override
public void save(Object objectToSave) {
public <T> T save(T objectToSave) {
Assert.notNull(objectToSave, "Object to save must not be null!");
save(objectToSave, determineEntityCollectionName(objectToSave));
return save(objectToSave, determineEntityCollectionName(objectToSave));
}
@Override
public void save(Object objectToSave, String collectionName) {
public <T> T save(T objectToSave, String collectionName) {
Assert.notNull(objectToSave, "Object to save must not be null!");
Assert.hasText(collectionName, "Collection name must not be null or empty!");
@ -1385,11 +1395,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1385,11 +1395,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
MongoPersistentEntity<?> entity = getPersistentEntity(objectToSave.getClass());
if (entity != null && entity.hasVersionProperty()) {
doSaveVersioned(objectToSave, entity, collectionName);
return;
return doSaveVersioned(objectToSave, entity, collectionName);
}
doSave(collectionName, objectToSave, this.mongoConverter);
return (T) doSave(collectionName, objectToSave, this.mongoConverter);
}
private <T> T doSaveVersioned(T objectToSave, MongoPersistentEntity<?> entity, String collectionName) {
@ -1398,42 +1407,43 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1398,42 +1407,43 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
entity.getPropertyAccessor(objectToSave), mongoConverter.getConversionService());
MongoPersistentProperty property = entity.getRequiredVersionProperty();
Number number = convertingAccessor.getProperty(property, Number.class);
Number number = (Number) convertingAccessor.getProperty(property, Number.class);
if (number != null) {
// Bump version number
convertingAccessor.setProperty(property, number.longValue() + 1);
maybeEmitEvent(new BeforeConvertEvent<>(objectToSave, collectionName));
assertUpdateableIdIfNotSet(objectToSave);
T toSave = (T) convertingAccessor.getBean();
maybeEmitEvent(new BeforeConvertEvent<>(toSave, collectionName));
assertUpdateableIdIfNotSet(toSave);
Document document = new Document();
this.mongoConverter.write(objectToSave, document);
this.mongoConverter.write(toSave, document);
maybeEmitEvent(new BeforeSaveEvent<>(objectToSave, document, collectionName));
maybeEmitEvent(new BeforeSaveEvent<>(toSave, document, collectionName));
Update update = Update.fromDocument(document, ID_FIELD);
// Create query for entity with the id and old version
MongoPersistentProperty idProperty = entity.getRequiredIdProperty();
Object id = entity.getIdentifierAccessor(objectToSave).getRequiredIdentifier();
Object id = entity.getIdentifierAccessor(toSave).getRequiredIdentifier();
Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(property.getName()).is(number));
UpdateResult result = doUpdate(collectionName, query, update, objectToSave.getClass(), false, false);
UpdateResult result = doUpdate(collectionName, query, update, toSave.getClass(), false, false);
if (result.getModifiedCount() == 0) {
throw new OptimisticLockingFailureException(
String.format("Cannot save entity %s with version %s to collection %s. Has it been modified meanwhile?", id,
number, collectionName));
}
maybeEmitEvent(new AfterSaveEvent<>(objectToSave, document, collectionName));
maybeEmitEvent(new AfterSaveEvent<>(toSave, document, collectionName));
return objectToSave;
return toSave;
}
doInsert(collectionName, objectToSave, this.mongoConverter);
return objectToSave;
return (T) doInsert(collectionName, objectToSave, this.mongoConverter);
}
protected <T> T doSave(String collectionName, T objectToSave, MongoWriter<T> writer) {
@ -1446,10 +1456,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -1446,10 +1456,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
maybeEmitEvent(new BeforeSaveEvent<>(objectToSave, dbDoc, collectionName));
Object id = saveDocument(collectionName, dbDoc, objectToSave.getClass());
populateIdIfNecessary(objectToSave, id);
maybeEmitEvent(new AfterSaveEvent<>(objectToSave, dbDoc, collectionName));
T saved = (T) populateIdIfNecessary(objectToSave, id);
maybeEmitEvent(new AfterSaveEvent<>(saved, dbDoc, collectionName));
return objectToSave;
return saved;
}
protected Object insertDocument(final String collectionName, final Document document, final Class<?> entityClass) {
@ -2674,10 +2684,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -2674,10 +2684,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
* @param id
*/
@SuppressWarnings("unchecked")
protected void populateIdIfNecessary(Object savedObject, Object id) {
protected Object populateIdIfNecessary(Object savedObject, Object id) {
if (id == null) {
return;
return null;
}
if (savedObject instanceof Map) {
@ -2685,7 +2695,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -2685,7 +2695,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
Map<String, Object> map = (Map<String, Object>) savedObject;
map.put(ID_FIELD, id);
return;
return map;
}
MongoPersistentProperty idProperty = getIdPropertyFor(savedObject.getClass());
@ -2700,7 +2710,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -2700,7 +2710,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
if (value == null) {
new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProperty, id);
}
return accessor.getBean();
}
return savedObject;
}
private MongoCollection<Document> getAndPrepareCollection(MongoDatabase db, String collectionName) {

19
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SimpleMongoRepository.java

@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support; @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -77,12 +78,10 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> { @@ -77,12 +78,10 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
Assert.notNull(entity, "Entity must not be null!");
if (entityInformation.isNew(entity)) {
mongoOperations.insert(entity, entityInformation.getCollectionName());
} else {
mongoOperations.save(entity, entityInformation.getCollectionName());
return mongoOperations.insert(entity, entityInformation.getCollectionName());
}
return entity;
return mongoOperations.save(entity, entityInformation.getCollectionName());
}
/*
@ -100,13 +99,11 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> { @@ -100,13 +99,11 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
if (allNew) {
List<S> result = source.stream().collect(Collectors.toList());
mongoOperations.insert(result, entityInformation.getCollectionName());
return result;
return new ArrayList<>(mongoOperations.insert(result, entityInformation.getCollectionName()));
}
} else {
return source.stream().map(this::save).collect(Collectors.toList());
}
}
/*
* (non-Javadoc)
@ -244,8 +241,7 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> { @@ -244,8 +241,7 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
Assert.notNull(entity, "Entity must not be null!");
mongoOperations.insert(entity, entityInformation.getCollectionName());
return entity;
return mongoOperations.insert(entity, entityInformation.getCollectionName());
}
/*
@ -263,8 +259,7 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> { @@ -263,8 +259,7 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
return list;
}
mongoOperations.insertAll(list);
return list;
return new ArrayList<>(mongoOperations.insertAll(list));
}
/*

29
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

@ -39,6 +39,7 @@ import java.util.*; @@ -39,6 +39,7 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import lombok.experimental.Wither;
import org.bson.types.ObjectId;
import org.hamcrest.collection.IsMapContaining;
import org.joda.time.DateTime;
@ -1638,6 +1639,21 @@ public class MongoTemplateTests { @@ -1638,6 +1639,21 @@ public class MongoTemplateTests {
assertThat(person.version, is(0));
}
@Test // DATAMONGO-1992
public void initializesIdAndVersionAndOfImmutableObject() {
ImmutableVersioned versioned = new ImmutableVersioned();
ImmutableVersioned saved = template.insert(versioned);
assertThat(saved, is(not(sameInstance(versioned))));
assertThat(versioned.id, is(nullValue()));
assertThat(versioned.version, is(nullValue()));
assertThat(saved.id, is(notNullValue()));
assertThat(saved.version, is(0L));
}
@Test(expected = IllegalArgumentException.class) // DATAMONGO-568, DATAMONGO-1762
public void queryCantBeNull() {
template.find(null, PersonWithIdPropertyOfTypeObjectId.class);
@ -4057,4 +4073,17 @@ public class MongoTemplateTests { @@ -4057,4 +4073,17 @@ public class MongoTemplateTests {
}
}
@AllArgsConstructor
@Wither
static class ImmutableVersioned {
final @Id String id;
final @Version Long version;
public ImmutableVersioned() {
id = null;
version = null;
}
}
}

Loading…
Cancel
Save