Browse Source

DATAMONGO-828 - Fixed version checks for updates in MongoTemplate.

Added inspection of the query object to check if the update should only apply to a given version. If so and no documents have been updated we still throw an OptimisticLockingException. For all other cases - like UpdateFirst - zero affected documents is fine.

Original Pull Request: #121.
pull/121/merge
Christoph Strobl 12 years ago committed by Oliver Gierke
parent
commit
617ebe0ca7
  1. 17
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  2. 12
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

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

@ -1016,7 +1016,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
: collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse); : collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse);
if (entity != null && entity.hasVersionProperty() && !multi) { if (entity != null && entity.hasVersionProperty() && !multi) {
if (writeResult.getN() == 0) { if (writeResult.getN() == 0 && dbObjectContainsVersionProperty(queryObj, entity)) {
throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: " throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: "
+ updateObj.toMap().toString() + " to collection " + collectionName); + updateObj.toMap().toString() + " to collection " + collectionName);
} }
@ -1031,14 +1031,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
private void increaseVersionForUpdateIfNecessary(MongoPersistentEntity<?> persistentEntity, Update update) { private void increaseVersionForUpdateIfNecessary(MongoPersistentEntity<?> persistentEntity, Update update) {
if (persistentEntity != null && persistentEntity.hasVersionProperty()) { if (persistentEntity != null && persistentEntity.hasVersionProperty()) {
if (!dbObjectContainsVersionProperty(update.getUpdateObject(), persistentEntity)) {
String versionPropertyField = persistentEntity.getVersionProperty().getFieldName(); update.inc(persistentEntity.getVersionProperty().getFieldName(), 1L);
if (!update.getUpdateObject().containsField(versionPropertyField)) {
update.inc(versionPropertyField, 1L);
} }
} }
} }
private boolean dbObjectContainsVersionProperty(DBObject dbObject, MongoPersistentEntity<?> persistentEntity) {
if (persistentEntity == null || !persistentEntity.hasVersionProperty()) {
return false;
}
return dbObject.containsField(persistentEntity.getVersionProperty().getFieldName());
}
public void remove(Object object) { public void remove(Object object) {
if (object == null) { if (object == null) {

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

@ -2290,6 +2290,18 @@ public class MongoTemplateTests {
assertThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(3)); assertThat(template.findOne(query, DocumentWithCollectionOfSimpleType.class).values, hasSize(3));
} }
/**
* @see DATAMONOGO-828
*/
@Test
public void updateFirstShouldDoNothingWhenCalledForEntitiesThatDoNotExist() {
Query q = query(where("id").is(Long.MIN_VALUE));
template.updateFirst(q, Update.update("lastname", "supercalifragilisticexpialidocious"), VersionedPerson.class);
assertThat(template.findOne(q, VersionedPerson.class), nullValue());
}
static class DocumentWithCollection { static class DocumentWithCollection {
@Id String id; @Id String id;

Loading…
Cancel
Save