diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java index 1e69eda3..89eb0028 100644 --- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java @@ -96,6 +96,21 @@ class CouchbaseTemplateSupport implements ApplicationContextAware { } } + public long getCas(final Object entity) { + final ConvertingPropertyAccessor accessor = getPropertyAccessor(entity); + final CouchbasePersistentEntity persistentEntity = mappingContext.getRequiredPersistentEntity(entity.getClass()); + final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty(); + + long cas = 0; + if (versionProperty != null) { + Object casObject = (Number)accessor.getProperty(versionProperty); + if (casObject instanceof Number){ + cas = ((Number)casObject).longValue(); + } + } + return cas; + } + public String getJavaNameForEntity(final Class clazz) { final CouchbasePersistentEntity persistentEntity = mappingContext.getRequiredPersistentEntity(clazz); MappingCouchbaseEntityInformation info = new MappingCouchbaseEntityInformation<>(persistentEntity); diff --git a/src/main/java/org/springframework/data/couchbase/core/ReactiveReplaceByIdOperationSupport.java b/src/main/java/org/springframework/data/couchbase/core/ReactiveReplaceByIdOperationSupport.java index 2c8c97ed..0ff9038a 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveReplaceByIdOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveReplaceByIdOperationSupport.java @@ -68,8 +68,8 @@ public class ReactiveReplaceByIdOperationSupport implements ReactiveReplaceByIdO return Mono.just(object).flatMap(o -> { CouchbaseDocument converted = template.support().encodeEntity(o); return template.getCollection(collection).reactive() - .replace(converted.getId(), converted.export(), buildReplaceOptions()).map(result -> { - template.support().applyUpdatedCas(object, result.cas()); + .replace(converted.getId(), converted.export(), buildReplaceOptions(o)).map(result -> { + template.support().applyUpdatedCas(o, result.cas()); return o; }); }).onErrorMap(throwable -> { @@ -86,13 +86,15 @@ public class ReactiveReplaceByIdOperationSupport implements ReactiveReplaceByIdO return Flux.fromIterable(objects).flatMap(this::one); } - private ReplaceOptions buildReplaceOptions() { + private ReplaceOptions buildReplaceOptions(T object) { final ReplaceOptions options = ReplaceOptions.replaceOptions(); if (persistTo != PersistTo.NONE || replicateTo != ReplicateTo.NONE) { options.durability(persistTo, replicateTo); } else if (durabilityLevel != DurabilityLevel.NONE) { options.durability(durabilityLevel); } + long cas = template.support().getCas(object); + options.cas(cas); return options; } diff --git a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java index 680dbe29..d0ebb50b 100644 --- a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java @@ -29,7 +29,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.dao.DataIntegrityViolationException;; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.couchbase.CouchbaseClientFactory; import org.springframework.data.couchbase.SimpleCouchbaseClientFactory; @@ -74,6 +74,12 @@ class CouchbaseTemplateKeyValueIntegrationTests extends ClusterAwareIntegrationT User modified = couchbaseTemplate.upsertById(User.class).one(user); assertEquals(user, modified); + modified = couchbaseTemplate.replaceById(User.class).one(user); + assertEquals(user, modified); + + user.setVersion(12345678); + assertThrows(DataIntegrityViolationException.class, () -> couchbaseTemplate.replaceById(User.class).one(user)); + User found = couchbaseTemplate.findById(User.class).one(user.getId()); assertEquals(user, found); diff --git a/src/test/java/org/springframework/data/couchbase/domain/User.java b/src/test/java/org/springframework/data/couchbase/domain/User.java index 5641742f..028202ae 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/User.java +++ b/src/test/java/org/springframework/data/couchbase/domain/User.java @@ -85,6 +85,10 @@ public class User { return version; } + public void setVersion(long version) { + this.version = version; + } + @Override public boolean equals(Object o) { if (this == o)