From 289fc7cd41b61ad73e8867f57edad914f8abd67b Mon Sep 17 00:00:00 2001 From: mikereiche Date: Tue, 8 Dec 2020 16:04:52 -0800 Subject: [PATCH] DATACOUCH-666 - Handle immutable entity in replace. --- .../ReactiveReplaceByIdOperationSupport.java | 6 +- ...hbaseTemplateKeyValueIntegrationTests.java | 67 +++++++++++++++++-- .../data/couchbase/domain/PersonValue.java | 3 +- ...aseRepositoryKeyValueIntegrationTests.java | 4 -- 4 files changed, 64 insertions(+), 16 deletions(-) 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 0ff9038a4..c5b4580f6 100644 --- a/src/main/java/org/springframework/data/couchbase/core/ReactiveReplaceByIdOperationSupport.java +++ b/src/main/java/org/springframework/data/couchbase/core/ReactiveReplaceByIdOperationSupport.java @@ -68,10 +68,8 @@ public Mono one(T object) { return Mono.just(object).flatMap(o -> { CouchbaseDocument converted = template.support().encodeEntity(o); return template.getCollection(collection).reactive() - .replace(converted.getId(), converted.export(), buildReplaceOptions(o)).map(result -> { - template.support().applyUpdatedCas(o, result.cas()); - return o; - }); + .replace(converted.getId(), converted.export(), buildReplaceOptions(o)).map(result -> + (T)template.support().applyUpdatedCas(o, result.cas())); }).onErrorMap(throwable -> { if (throwable instanceof RuntimeException) { return template.potentiallyConvertRuntimeException((RuntimeException) throwable); 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 5ceaaa63b..7afbbd64d 100644 --- a/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/core/CouchbaseTemplateKeyValueIntegrationTests.java @@ -16,35 +16,44 @@ package org.springframework.data.couchbase.core; -import static org.junit.jupiter.api.Assertions.*; -import static org.springframework.data.couchbase.config.BeanNames.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE; +import static org.springframework.data.couchbase.config.BeanNames.REACTIVE_COUCHBASE_TEMPLATE; import java.io.IOException; import java.time.Duration; import java.util.UUID; -import com.couchbase.client.core.error.DocumentNotFoundException; -import com.couchbase.client.java.kv.PersistTo; -import com.couchbase.client.java.kv.ReplicateTo; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; 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.DataIntegrityViolationException; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.couchbase.CouchbaseClientFactory; import org.springframework.data.couchbase.SimpleCouchbaseClientFactory; import org.springframework.data.couchbase.domain.Config; +import org.springframework.data.couchbase.domain.PersonValue; import org.springframework.data.couchbase.domain.User; import org.springframework.data.couchbase.domain.UserAnnotated; import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests; import org.springframework.data.couchbase.util.ClusterType; import org.springframework.data.couchbase.util.IgnoreWhen; +import com.couchbase.client.java.kv.PersistTo; +import com.couchbase.client.java.kv.ReplicateTo; + +; + /** * KV tests Theses tests rely on a cb server running. * @@ -251,6 +260,50 @@ void existsById() { } + @Test + @IgnoreWhen(clusterTypes = ClusterType.MOCKED) + void saveAndFindImmutableById() { + PersonValue personValue = new PersonValue(null, 123, "f", "l"); + System.out.println("personValue: " + personValue); + // personValue = personValue.withVersion(123); + PersonValue inserted = null; + PersonValue upserted = null; + PersonValue replaced = null; + + try { + + inserted = couchbaseTemplate.insertById(PersonValue.class).one(personValue); + assertNotEquals(0, inserted.getVersion()); + PersonValue foundInserted = couchbaseTemplate.findById(PersonValue.class).one(inserted.getId()); + assertNotNull(foundInserted, "inserted personValue not found"); + assertEquals(inserted, foundInserted); + + // upsert will be inserted + couchbaseTemplate.removeById().one(inserted.getId()); + upserted = couchbaseTemplate.upsertById(PersonValue.class).one(inserted); + assertNotEquals(0, upserted.getVersion()); + PersonValue foundUpserted = couchbaseTemplate.findById(PersonValue.class).one(upserted.getId()); + assertNotNull(foundUpserted, "upserted personValue not found"); + assertEquals(upserted, foundUpserted); + + // upsert will be replaced + upserted = couchbaseTemplate.upsertById(PersonValue.class).one(inserted); + assertNotEquals(0, upserted.getVersion()); + PersonValue foundUpserted2 = couchbaseTemplate.findById(PersonValue.class).one(upserted.getId()); + assertNotNull(foundUpserted2, "upserted personValue not found"); + assertEquals(upserted, foundUpserted2); + + replaced = couchbaseTemplate.replaceById(PersonValue.class).one(upserted); + assertNotEquals(0, replaced.getVersion()); + PersonValue foundReplaced = couchbaseTemplate.findById(PersonValue.class).one(replaced.getId()); + assertNotNull(foundReplaced, "replaced personValue not found"); + assertEquals(replaced, foundReplaced); + + } finally { + couchbaseTemplate.removeById().one(inserted.getId()); + } + } + private void sleepSecs(int i) { try { Thread.sleep(i * 1000); diff --git a/src/test/java/org/springframework/data/couchbase/domain/PersonValue.java b/src/test/java/org/springframework/data/couchbase/domain/PersonValue.java index b98046c01..32c968112 100644 --- a/src/test/java/org/springframework/data/couchbase/domain/PersonValue.java +++ b/src/test/java/org/springframework/data/couchbase/domain/PersonValue.java @@ -35,7 +35,8 @@ public class PersonValue { @Id @GeneratedValue(strategy = GenerationStrategy.UNIQUE) @With String id; -// @Version @With + @Version + @With long version; @Field String firstname; @Field String lastname; diff --git a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryKeyValueIntegrationTests.java b/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryKeyValueIntegrationTests.java index 5b18b05f0..41612eedd 100644 --- a/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryKeyValueIntegrationTests.java +++ b/src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryKeyValueIntegrationTests.java @@ -99,13 +99,9 @@ void saveAndFindById() { @IgnoreWhen(clusterTypes = ClusterType.MOCKED) void saveAndFindImmutableById() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { PersonValue personValue = new PersonValue(null, 0, "f", "l"); - //assertFalse(personValueRepository.existsById(personValue.getId())); personValue = personValueRepository.save(personValue); Optional found = personValueRepository.findById(personValue.getId()); assertTrue(found.isPresent()); - Method m = PersonValue.class.getMethod("equals", Object.class); - m.invoke(personValue, new Object[] { found.get() }); - personValue.equals(found.get()); assertEquals(personValue, found.get()); personValueRepository.delete(personValue); }