From b9c8b7b23423037fad8fe88c530d32b1cf182575 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 10 Feb 2014 13:13:15 +0100 Subject: [PATCH] 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. --- .../data/mongodb/core/MongoTemplate.java | 17 ++++++++++++----- .../data/mongodb/core/MongoTemplateTests.java | 12 ++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) 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 85f913bbf..bb5a58bae 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 @@ -1012,7 +1012,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { : collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse); 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: " + updateObj.toMap().toString() + " to collection " + collectionName); } @@ -1027,14 +1027,21 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { private void increaseVersionForUpdateIfNecessary(MongoPersistentEntity persistentEntity, Update update) { if (persistentEntity != null && persistentEntity.hasVersionProperty()) { - - String versionPropertyField = persistentEntity.getVersionProperty().getFieldName(); - if (!update.getUpdateObject().containsField(versionPropertyField)) { - update.inc(versionPropertyField, 1L); + if (!dbObjectContainsVersionProperty(update.getUpdateObject(), persistentEntity)) { + update.inc(persistentEntity.getVersionProperty().getFieldName(), 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) { if (object == null) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 50e5a37af..baba4e9c1 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -2231,6 +2231,18 @@ public class MongoTemplateTests { assertThat(result.model.get(0).value(), is(newModelValue)); } + /** + * @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 { @Id public String id;