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 59b79664c..b1d32978f 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 @@ -997,16 +997,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, doInsert(collectionName, objectToSave, this.mongoConverter); } else { - maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); - assertUpdateableIdIfNotSet(objectToSave); - - // Create query for entity with the id and old version - Object id = convertingAccessor.getProperty(idProperty); - Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(versionProperty.getName()).is(version)); - // Bump version number convertingAccessor.setProperty(versionProperty, versionNumber.longValue() + 1); + maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); + assertUpdateableIdIfNotSet(objectToSave); + Document document = new Document(); this.mongoConverter.write(objectToSave, document); @@ -1014,6 +1010,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, maybeEmitEvent(new BeforeSaveEvent(objectToSave, document, collectionName)); Update update = Update.fromDocument(document, ID_FIELD); + // Create query for entity with the id and old version + Object id = convertingAccessor.getProperty(idProperty); + Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(versionProperty.getName()).is(version)); + UpdateResult result = doUpdate(collectionName, query, update, objectToSave.getClass(), false, false); if (result.getModifiedCount() == 0) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java index 501f02d19..857c17401 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateUnitTests.java @@ -56,6 +56,8 @@ import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.QueryMapper; import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener; +import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent; import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Criteria; @@ -75,6 +77,7 @@ import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.FindOneAndUpdateOptions; import com.mongodb.client.model.UpdateOptions; +import com.mongodb.client.result.UpdateResult; /** * Unit tests for {@link MongoTemplate}. @@ -498,6 +501,36 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests { verify(output, times(1)).limit(1000); } + @Test // DATAMONGO-1639 + public void beforeConvertEventForUpdateSeesNextVersion() { + + final VersionedEntity entity = new VersionedEntity(); + entity.id = 1; + entity.version = 0; + + GenericApplicationContext context = new GenericApplicationContext(); + context.refresh(); + context.addApplicationListener(new AbstractMongoEventListener() { + + @Override + public void onBeforeConvert(BeforeConvertEvent event) { + assertThat(event.getSource().version, is(1)); + } + }); + + template.setApplicationContext(context); + + MongoTemplate spy = Mockito.spy(template); + + UpdateResult result = mock(UpdateResult.class); + doReturn(1L).when(result).getModifiedCount(); + + doReturn(result).when(spy).doUpdate(anyString(), Mockito.any(Query.class), Mockito.any(Update.class), + Mockito.any(Class.class), anyBoolean(), anyBoolean()); + + spy.save(entity); + } + class AutogenerateableId { @Id BigInteger id;