DATAMONGO-2155 - Introduce UpdateDefinition.
Original pull request: #625.
This commit is contained in:
committed by
Mark Paluch
parent
9f8d081ef3
commit
a759dff5fd
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||
import org.springframework.data.util.StreamUtils;
|
||||
|
||||
import com.mongodb.client.model.Filters;
|
||||
@@ -86,17 +87,55 @@ public class MappedDocument {
|
||||
return new MappedUpdate(Update.fromDocument(document, ID_FIELD));
|
||||
}
|
||||
|
||||
public class MappedUpdate extends Update {
|
||||
/**
|
||||
* An {@link UpdateDefinition} that indicates that the {@link #getUpdateObject() update object} has already been
|
||||
* mapped to the specific domain type.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.2
|
||||
*/
|
||||
public class MappedUpdate implements UpdateDefinition {
|
||||
|
||||
private final Update delegate;
|
||||
|
||||
public MappedUpdate(Update delegate) {
|
||||
MappedUpdate(Update delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#getUpdateObject()
|
||||
*/
|
||||
@Override
|
||||
public Document getUpdateObject() {
|
||||
return delegate.getUpdateObject();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#modifies(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean modifies(String key) {
|
||||
return delegate.modifies(key);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#incVersion(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void incVersion(String version) {
|
||||
delegate.incVersion(version);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#isIsolated()
|
||||
*/
|
||||
@Override
|
||||
public Boolean isIsolated() {
|
||||
return delegate.isIsolated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ import org.springframework.data.mongodb.core.query.Meta;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||
import org.springframework.data.mongodb.core.validation.Validator;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.util.CloseableIterator;
|
||||
@@ -1555,7 +1556,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
return doUpdate(collectionName, query, update, entityClass, false, true);
|
||||
}
|
||||
|
||||
protected UpdateResult doUpdate(final String collectionName, final Query query, final Update update,
|
||||
protected UpdateResult doUpdate(final String collectionName, final Query query, final UpdateDefinition update,
|
||||
@Nullable final Class<?> entityClass, final boolean upsert, final boolean multi) {
|
||||
|
||||
Assert.notNull(collectionName, "CollectionName must not be null!");
|
||||
@@ -1616,12 +1617,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
});
|
||||
}
|
||||
|
||||
private void increaseVersionForUpdateIfNecessary(@Nullable MongoPersistentEntity<?> persistentEntity, Update update) {
|
||||
private void increaseVersionForUpdateIfNecessary(@Nullable MongoPersistentEntity<?> persistentEntity, UpdateDefinition update) {
|
||||
|
||||
if (persistentEntity != null && persistentEntity.hasVersionProperty()) {
|
||||
String versionFieldName = persistentEntity.getRequiredVersionProperty().getFieldName();
|
||||
if (!update.modifies(versionFieldName)) {
|
||||
update.inc(versionFieldName, 1L);
|
||||
update.incVersion(versionFieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ import org.springframework.data.mongodb.core.query.Meta;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.query.Update;
|
||||
import org.springframework.data.mongodb.core.query.UpdateDefinition;
|
||||
import org.springframework.data.mongodb.core.validation.Validator;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.util.Optionals;
|
||||
@@ -1611,7 +1612,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
return doUpdate(collectionName, query, update, entityClass, false, true);
|
||||
}
|
||||
|
||||
protected Mono<UpdateResult> doUpdate(String collectionName, Query query, @Nullable Update update,
|
||||
protected Mono<UpdateResult> doUpdate(String collectionName, Query query, @Nullable UpdateDefinition update,
|
||||
@Nullable Class<?> entityClass, boolean upsert, boolean multi) {
|
||||
|
||||
MongoPersistentEntity<?> entity = entityClass == null ? null : getPersistentEntity(entityClass);
|
||||
@@ -1668,12 +1669,13 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
return result.next();
|
||||
}
|
||||
|
||||
private void increaseVersionForUpdateIfNecessary(@Nullable MongoPersistentEntity<?> persistentEntity, Update update) {
|
||||
private void increaseVersionForUpdateIfNecessary(@Nullable MongoPersistentEntity<?> persistentEntity,
|
||||
UpdateDefinition update) {
|
||||
|
||||
if (persistentEntity != null && persistentEntity.hasVersionProperty()) {
|
||||
String versionFieldName = persistentEntity.getRequiredVersionProperty().getFieldName();
|
||||
if (!update.modifies(versionFieldName)) {
|
||||
update.inc(versionFieldName, 1L);
|
||||
update.incVersion(versionFieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Mark Paluch
|
||||
* @author Pavel Vodrazka
|
||||
*/
|
||||
public class Update {
|
||||
public class Update implements UpdateDefinition {
|
||||
|
||||
public enum Position {
|
||||
LAST, FIRST
|
||||
@@ -155,6 +155,15 @@ public class Update {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#incVersion()
|
||||
*/
|
||||
@Override
|
||||
public void incVersion(String key) {
|
||||
inc(key, 1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update using the {@literal $push} update modifier
|
||||
*
|
||||
@@ -390,14 +399,18 @@ public class Update {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if update isolated is set.
|
||||
* @since 2.0
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#isIsolated()
|
||||
*/
|
||||
public Boolean isIsolated() {
|
||||
return isolated;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#getUpdateObject()
|
||||
*/
|
||||
public Document getUpdateObject() {
|
||||
return new Document(modifierOps);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2018 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.query;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Interface fixing must have operations for {@literal updates} as implemented via {@link Update}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.2
|
||||
*/
|
||||
public interface UpdateDefinition {
|
||||
|
||||
/**
|
||||
* If {@literal true} prevents a write operation that affects <strong>multiple</strong> documents from yielding to
|
||||
* other reads or writes once the first document is written. <br />
|
||||
*
|
||||
* @return {@literal true} if update isolated is set.
|
||||
*/
|
||||
Boolean isIsolated();
|
||||
|
||||
/**
|
||||
* @return the actual update in its native {@link Document} format. Never {@literal null}.
|
||||
*/
|
||||
Document getUpdateObject();
|
||||
|
||||
/**
|
||||
* Check if a given {@literal key} is modified by applying the update.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @return {@literal true} if the actual {@link UpdateDefinition} attempts to modify the given {@literal key}.
|
||||
*/
|
||||
boolean modifies(String key);
|
||||
|
||||
/**
|
||||
* Bump the version of a given {@literal key} by {@code 1}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
*/
|
||||
void incVersion(String key);
|
||||
}
|
||||
@@ -537,6 +537,8 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
@Test // DATAMONGO-1639
|
||||
public void beforeConvertEventForUpdateSeesNextVersion() {
|
||||
|
||||
when(updateResult.getModifiedCount()).thenReturn(1L);
|
||||
|
||||
final VersionedEntity entity = new VersionedEntity();
|
||||
entity.id = 1;
|
||||
entity.version = 0;
|
||||
@@ -553,15 +555,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
|
||||
template.setApplicationContext(context);
|
||||
|
||||
MongoTemplate spy = Mockito.spy(template);
|
||||
|
||||
UpdateResult result = mock(UpdateResult.class);
|
||||
doReturn(1L).when(result).getModifiedCount();
|
||||
|
||||
doReturn(result).when(spy).doUpdate(anyString(), any(Query.class), any(Update.class), any(Class.class),
|
||||
anyBoolean(), anyBoolean());
|
||||
|
||||
spy.save(entity);
|
||||
template.save(entity);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1447
|
||||
|
||||
Reference in New Issue
Block a user