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 2facec8c3..e58f166e0 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 @@ -127,6 +127,7 @@ import com.mongodb.util.JSONParseException; * @author Sebastian Herold * @author Thomas Darimont * @author Chuong Ngo + * @author Christoph Strobl */ public class MongoTemplate implements MongoOperations, ApplicationContextAware { @@ -996,6 +997,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { MongoPersistentEntity entity = entityClass == null ? null : getPersistentEntity(entityClass); + increaseVersionForUpdateIfNecessary(entity, update); + DBObject queryObj = query == null ? new BasicDBObject() : queryMapper.getMappedObject(query.getQueryObject(), entity); DBObject updateObj = update == null ? new BasicDBObject() : updateMapper.getMappedObject( @@ -1025,6 +1028,17 @@ 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); + } + } + } + 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 1d37d3b4b..8abf2de41 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 @@ -94,6 +94,7 @@ import com.mongodb.WriteResult; * @author Patryk Wasik * @author Thomas Darimont * @author Komi Innocent + * @author Christoph Strobl */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:infrastructure.xml") @@ -2087,6 +2088,79 @@ public class MongoTemplateTests { }); } + /** + * @see DATAMONGO-811 + */ + @Test + public void updateFirstShouldIncreaseVersionForVersionedEntity() { + + VersionedPerson person = new VersionedPerson(); + person.firstname = "Dave"; + person.lastname = "Matthews"; + template.save(person); + assertThat(person.id, is(notNullValue())); + + Query qry = query(where("id").is(person.id)); + VersionedPerson personAfterFirstSave = template.findOne(qry, VersionedPerson.class); + assertThat(personAfterFirstSave.version, is(0L)); + + template.updateFirst(qry, Update.update("lastname", "Bubu"), VersionedPerson.class); + + VersionedPerson personAfterUpdateFirst = template.findOne(qry, VersionedPerson.class); + assertThat(personAfterUpdateFirst.version, is(1L)); + assertThat(personAfterUpdateFirst.lastname, is("Bubu")); + } + + /** + * @see DATAMONGO-811 + */ + @Test + public void updateFirstShouldIncreaseVersionOnlyForFirstMatchingEntity() { + + VersionedPerson person1 = new VersionedPerson(); + person1.firstname = "Dave"; + + VersionedPerson person2 = new VersionedPerson(); + person2.firstname = "Dave"; + + template.save(person1); + template.save(person2); + Query q = query(where("id").in(person1.id, person2.id)); + + template.updateFirst(q, Update.update("lastname", "Metthews"), VersionedPerson.class); + + for (VersionedPerson p : template.find(q, VersionedPerson.class)) { + if ("Metthews".equals(p.lastname)) { + assertThat(p.version, equalTo(Long.valueOf(1))); + } else { + assertThat(p.version, equalTo(Long.valueOf(0))); + } + } + } + + /** + * @see DATAMONGO-811 + */ + @Test + public void updateMultiShouldIncreaseVersionOfAllUpdatedEntities() { + + VersionedPerson person1 = new VersionedPerson(); + person1.firstname = "Dave"; + + VersionedPerson person2 = new VersionedPerson(); + person2.firstname = "Dave"; + + template.save(person1); + template.save(person2); + + Query q = query(where("id").in(person1.id, person2.id)); + template.updateMulti(q, Update.update("lastname", "Metthews"), VersionedPerson.class); + + for (VersionedPerson p : template.find(q, VersionedPerson.class)) { + assertThat(p.version, equalTo(Long.valueOf(1))); + } + } + static interface Model { String value();