From 33a81f86d307a1be5569dbada63f70aa8f6d0c7d Mon Sep 17 00:00:00 2001 From: agrgr Date: Tue, 10 Dec 2024 12:01:25 +0200 Subject: [PATCH] use new Policy instances when enriching with transaction id --- .../aerospike/core/AerospikeTemplate.java | 42 +++++----- .../data/aerospike/core/TemplateUtils.java | 27 +++++-- ...tiveAerospikeTemplateTransactionTests.java | 32 ++++++-- ...AerospikeTemplateTransactionUnitTests.java | 4 +- .../AerospikeTemplateTransactionTests.java | 15 ++++ ...AerospikeTransactionalAnnotationTests.java | 77 ++++++++----------- 6 files changed, 119 insertions(+), 78 deletions(-) diff --git a/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java b/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java index 4961674c..f4cfc2ef 100644 --- a/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java +++ b/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java @@ -76,7 +76,7 @@ import static org.springframework.data.aerospike.core.CoreUtils.getDistinctPredicate; import static org.springframework.data.aerospike.core.CoreUtils.operations; import static org.springframework.data.aerospike.core.CoreUtils.verifyUnsortedWithOffset; -import static org.springframework.data.aerospike.core.TemplateUtils.checkForTransaction; +import static org.springframework.data.aerospike.core.TemplateUtils.enrichPolicyWithTransaction; import static org.springframework.data.aerospike.core.TemplateUtils.excludeIdQualifier; import static org.springframework.data.aerospike.core.TemplateUtils.getBinNamesFromTargetClass; import static org.springframework.data.aerospike.core.TemplateUtils.getIdValue; @@ -208,7 +208,7 @@ private void batchWriteAllDocuments(List documents, String setName, Opera List batchWriteRecords = batchWriteDataList.stream().map(BatchWriteData::batchRecord).toList(); try { - BatchPolicy bPolicy = (BatchPolicy) checkForTransaction(client, client.getBatchPolicyDefault()); + BatchPolicy bPolicy = (BatchPolicy) enrichPolicyWithTransaction(client, client.getBatchPolicyDefault()); client.operate(bPolicy, batchWriteRecords); } catch (AerospikeException e) { throw translateError(e); // no exception is thrown for versions mismatch, only record's result code shows it @@ -401,7 +401,7 @@ public boolean delete(T document, String setName) { private boolean doDeleteWithVersionAndHandleCasError(AerospikeWriteData data) { try { WritePolicy writePolicy = expectGenerationPolicy(data, RecordExistsAction.UPDATE_ONLY); - writePolicy = (WritePolicy) checkForTransaction(client, writePolicy); + writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, writePolicy); return client.delete(writePolicy, data.getKey()); } catch (AerospikeException e) { throw translateCasError(e, "Failed to delete record due to versions mismatch"); @@ -411,7 +411,7 @@ private boolean doDeleteWithVersionAndHandleCasError(AerospikeWriteData data) { private boolean doDeleteIgnoreVersionAndTranslateError(AerospikeWriteData data) { try { WritePolicy writePolicy = ignoreGenerationPolicy(data, RecordExistsAction.UPDATE_ONLY); - writePolicy = (WritePolicy) checkForTransaction(client, writePolicy); + writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, writePolicy); return client.delete(writePolicy, data.getKey()); } catch (AerospikeException e) { throw translateError(e); @@ -431,7 +431,7 @@ public boolean deleteById(Object id, String setName) { try { Key key = getKey(id, setName); - WritePolicy writePolicy = (WritePolicy) checkForTransaction(client, ignoreGenerationPolicy()); + WritePolicy writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, ignoreGenerationPolicy()); return client.delete(writePolicy, key); } catch (AerospikeException e) { throw translateError(e); @@ -593,7 +593,7 @@ public void deleteAll(String setName, Instant beforeLastUpdate) { private void deleteAndHandleErrors(IAerospikeClient client, Key[] keys) { BatchResults results; try { - BatchPolicy batchPolicy = (BatchPolicy) checkForTransaction(client, client.getBatchPolicyDefault()); + BatchPolicy batchPolicy = (BatchPolicy) enrichPolicyWithTransaction(client, client.getBatchPolicyDefault()); results = client.delete(batchPolicy, null, keys); } catch (AerospikeException e) { throw translateError(e); @@ -630,7 +630,7 @@ public T add(T document, String setName, Map values) { WritePolicy writePolicy = WritePolicyBuilder.builder(client.getWritePolicyDefault()) .expiration(data.getExpiration()) .build(); - writePolicy = (WritePolicy) checkForTransaction(client, writePolicy); + writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, writePolicy); Record aeroRecord = client.operate(writePolicy, data.getKey(), ops); @@ -657,7 +657,7 @@ public T add(T document, String setName, String binName, long value) { WritePolicy writePolicy = WritePolicyBuilder.builder(client.getWritePolicyDefault()) .expiration(data.getExpiration()) .build(); - writePolicy = (WritePolicy) checkForTransaction(client, writePolicy); + writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, writePolicy); Record aeroRecord = client.operate(writePolicy, data.getKey(), Operation.add(new Bin(binName, value)), Operation.get()); @@ -682,7 +682,7 @@ public T append(T document, String setName, Map values) { try { AerospikeWriteData data = writeData(document, setName); Operation[] ops = operations(values, Operation.Type.APPEND, Operation.get()); - WritePolicy writePolicy = (WritePolicy) checkForTransaction(client, client.getWritePolicyDefault()); + WritePolicy writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, client.getWritePolicyDefault()); Record aeroRecord = client.operate(writePolicy, data.getKey(), ops); return mapToEntity(data.getKey(), getEntityClass(document), aeroRecord); @@ -704,7 +704,7 @@ public T append(T document, String setName, String binName, String value) { try { AerospikeWriteData data = writeData(document, setName); - WritePolicy writePolicy = (WritePolicy) checkForTransaction(client, client.getWritePolicyDefault()); + WritePolicy writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, client.getWritePolicyDefault()); Record aeroRecord = client.operate(writePolicy, data.getKey(), Operation.append(new Bin(binName, value)), Operation.get(binName)); @@ -728,7 +728,7 @@ public T prepend(T document, String setName, String fieldName, String value) try { AerospikeWriteData data = writeData(document, setName); - WritePolicy writePolicy = (WritePolicy) checkForTransaction(client, client.getWritePolicyDefault()); + WritePolicy writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, client.getWritePolicyDefault()); Record aeroRecord = client.operate(writePolicy, data.getKey(), Operation.prepend(new Bin(fieldName, value)), Operation.get(fieldName)); @@ -753,7 +753,7 @@ public T prepend(T document, String setName, Map values) { try { AerospikeWriteData data = writeData(document, setName); Operation[] ops = operations(values, Operation.Type.PREPEND, Operation.get()); - WritePolicy writePolicy = (WritePolicy) checkForTransaction(client, client.getWritePolicyDefault()); + WritePolicy writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, client.getWritePolicyDefault()); Record aeroRecord = client.operate(writePolicy, data.getKey(), ops); return mapToEntity(data.getKey(), getEntityClass(document), aeroRecord); @@ -808,7 +808,7 @@ private Record getRecord(AerospikePersistentEntity entity, Key key, @Nullable Assert.state(!entity.hasExpirationProperty(), "Touch on read is not supported for expiration property"); aeroRecord = getAndTouch(key, entity.getExpiration(), null, null); } else { - Policy policy = checkForTransaction(client, getPolicyFilterExpOrDefault(client, queryEngine, query)); + Policy policy = enrichPolicyWithTransaction(client, getPolicyFilterExpOrDefault(client, queryEngine, query)); aeroRecord = client.get(policy, key); } return aeroRecord; @@ -838,7 +838,7 @@ private Object getRecordMapToTargetClass(AerospikePersistentEntity entity Assert.state(!entity.hasExpirationProperty(), "Touch on read is not supported for expiration property"); aeroRecord = getAndTouch(key, entity.getExpiration(), binNames, query); } else { - Policy policy = checkForTransaction(client, getPolicyFilterExpOrDefault(client, queryEngine, query)); + Policy policy = enrichPolicyWithTransaction(client, getPolicyFilterExpOrDefault(client, queryEngine, query)); aeroRecord = client.get(policy, key, binNames); } return mapToEntity(key, targetClass, aeroRecord); @@ -863,7 +863,7 @@ private Record getAndTouch(Key key, int expiration, String[] binNames, @Nullable writePolicyBuilder.filterExp(queryEngine.getFilterExpressionsBuilder().build(qualifier)); } WritePolicy writePolicy = writePolicyBuilder.build(); - writePolicy = (WritePolicy) checkForTransaction(client, writePolicy); + writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, writePolicy); try { if (binNames == null || binNames.length == 0) { @@ -944,7 +944,7 @@ public GroupedEntities findByIds(GroupedKeys groupedKeys) { private GroupedEntities findGroupedEntitiesByGroupedKeys(GroupedKeys groupedKeys) { EntitiesKeys entitiesKeys = EntitiesKeys.of(toEntitiesKeyMap(groupedKeys)); - BatchPolicy bPolicy = (BatchPolicy) checkForTransaction(client, client.getBatchPolicyDefault()); + BatchPolicy bPolicy = (BatchPolicy) enrichPolicyWithTransaction(client, client.getBatchPolicyDefault()); Record[] aeroRecords = client.get(bPolicy, entitiesKeys.getKeys()); return toGroupedEntities(entitiesKeys, aeroRecords); @@ -1000,7 +1000,7 @@ public List findByIdsUsingQuery(Collection ids, Class entityClas .map(id -> getKey(id, setName)) .toArray(Key[]::new); - BatchPolicy batchPolicy = (BatchPolicy) checkForTransaction(client, getBatchPolicyFilterExp(query)); + BatchPolicy batchPolicy = (BatchPolicy) enrichPolicyWithTransaction(client, getBatchPolicyFilterExp(query)); Class target; Record[] aeroRecords; if (targetClass != null && targetClass != entityClass) { @@ -1170,7 +1170,7 @@ public boolean exists(Object id, String setName) { try { Key key = getKey(id, setName); - WritePolicy writePolicy = (WritePolicy) checkForTransaction(client, client.getWritePolicyDefault()); + WritePolicy writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, client.getWritePolicyDefault()); Record aeroRecord = client.operate(writePolicy, key, Operation.getHeader()); return aeroRecord != null; } catch (AerospikeException e) { @@ -1426,7 +1426,7 @@ public boolean indexExists(String indexName) { private Record doPersistAndHandleError(AerospikeWriteData data, WritePolicy writePolicy, Operation[] operations) { try { - writePolicy = (WritePolicy) checkForTransaction(client, writePolicy); + writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, writePolicy); return client.operate(writePolicy, data.getKey(), operations); } catch (AerospikeException e) { throw translateError(e); @@ -1455,7 +1455,7 @@ private void doPersistWithVersionAndHandleError(T document, AerospikeWriteDa private Record putAndGetHeader(AerospikeWriteData data, WritePolicy writePolicy, boolean firstlyDeleteBins) { Key key = data.getKey(); Operation[] operations = getPutAndGetHeaderOperations(data, firstlyDeleteBins); - writePolicy = (WritePolicy) checkForTransaction(client, writePolicy); + writePolicy = (WritePolicy) enrichPolicyWithTransaction(client, writePolicy); return client.operate(writePolicy, key, operations); } @@ -1540,7 +1540,7 @@ private List findByIdsWithoutMapping(Collection ids, String setNam try { Key[] keys = getKeys(ids, setName); - BatchPolicy bPolicy = (BatchPolicy) checkForTransaction(client, getBatchPolicyFilterExp(query)); + BatchPolicy bPolicy = (BatchPolicy) enrichPolicyWithTransaction(client, getBatchPolicyFilterExp(query)); Record[] aeroRecords; if (targetClass != null) { String[] binNames = getBinNamesFromTargetClass(targetClass, mappingContext); diff --git a/src/main/java/org/springframework/data/aerospike/core/TemplateUtils.java b/src/main/java/org/springframework/data/aerospike/core/TemplateUtils.java index da734c69..4a66d1b7 100644 --- a/src/main/java/org/springframework/data/aerospike/core/TemplateUtils.java +++ b/src/main/java/org/springframework/data/aerospike/core/TemplateUtils.java @@ -1,7 +1,9 @@ package org.springframework.data.aerospike.core; import com.aerospike.client.IAerospikeClient; +import com.aerospike.client.policy.BatchPolicy; import com.aerospike.client.policy.Policy; +import com.aerospike.client.policy.WritePolicy; import com.aerospike.client.reactor.IAerospikeReactorClient; import lombok.experimental.UtilityClass; import org.springframework.data.aerospike.mapping.AerospikePersistentEntity; @@ -126,16 +128,27 @@ public static String[] getBinNamesFromTargetClass(Class targetClass, return binNamesList.toArray(new String[0]); } - public static Policy checkForTransaction(IAerospikeClient client, Policy policy) { + public static Policy enrichPolicyWithTransaction(IAerospikeClient client, Policy policy) { if (TransactionSynchronizationManager.hasResource(client)) { AerospikeTransactionResourceHolder resourceHolder = (AerospikeTransactionResourceHolder) TransactionSynchronizationManager.getResource(client); - if (resourceHolder != null) policy.txn = resourceHolder.getTransaction(); - return policy; + Policy newPolicy = getNewPolicy(policy); + if (resourceHolder != null) newPolicy.txn = resourceHolder.getTransaction(); + return newPolicy; } return policy; } + private static Policy getNewPolicy(Policy policy) { + if (policy instanceof WritePolicy writePolicy) { + return new WritePolicy(writePolicy); + } else if (policy instanceof BatchPolicy batchPolicy) { + return new BatchPolicy(batchPolicy); + } else { + return new Policy(policy); + } + } + private static Policy getPolicyFilterExp(IAerospikeClient client, QueryEngine queryEngine, Query query) { if (queryCriteriaIsNotNull(query)) { Policy policy = new Policy(client.getReadPolicyDefault()); @@ -148,7 +161,7 @@ private static Policy getPolicyFilterExp(IAerospikeClient client, QueryEngine qu static Policy getPolicyFilterExpOrDefault(IAerospikeClient client, QueryEngine queryEngine, Query query) { Policy policy = getPolicyFilterExp(client, queryEngine, query); - return checkForTransaction(client, policy != null ? policy : client.getReadPolicyDefault()); + return policy != null ? policy : new Policy(client.getReadPolicyDefault()); } static Mono enrichPolicyWithTransaction(IAerospikeReactorClient reactiveClient, Policy policy) { @@ -156,7 +169,11 @@ static Mono enrichPolicyWithTransaction(IAerospikeReactorClient reactive .map(ctx -> { AerospikeReactiveTransactionResourceHolder resourceHolder = (AerospikeReactiveTransactionResourceHolder) ctx.getResources().get(reactiveClient); - if (resourceHolder != null) policy.txn = resourceHolder.getTransaction(); + if (resourceHolder != null) { + Policy newPolicy = getNewPolicy(policy); + newPolicy.txn = resourceHolder.getTransaction(); + return newPolicy; + } return policy; }) .onErrorResume(NoTransactionException.class, ignored -> diff --git a/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionTests.java b/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionTests.java index 281af25e..e22e6cb4 100644 --- a/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionTests.java +++ b/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionTests.java @@ -43,7 +43,6 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; @Slf4j @@ -131,8 +130,8 @@ public void verifyMultipleWritesInTransaction() { @Test public void verifyMultipleWritesInTransactionWithTimeout() { // Multi-record transactions are supported starting with Server version 8.0+ - SampleClasses.DocumentWithIntegerId document1 = new SampleClasses.DocumentWithIntegerId(501, "test1"); - SampleClasses.DocumentWithIntegerId document2 = new SampleClasses.DocumentWithIntegerId(501, "test2"); + SampleClasses.DocumentWithIntegerId document1 = new SampleClasses.DocumentWithIntegerId(520, "test1"); + SampleClasses.DocumentWithIntegerId document2 = new SampleClasses.DocumentWithIntegerId(520, "test2"); reactiveTemplate.insert(document1) // wait less than the specified timeout for this transactional operator @@ -144,7 +143,7 @@ public void verifyMultipleWritesInTransactionWithTimeout() { .verifyComplete(); reactiveTemplate - .findById(501, SampleClasses.DocumentWithIntegerId.class) + .findById(520, SampleClasses.DocumentWithIntegerId.class) .as(StepVerifier::create) .consumeNextWith(result -> assertThat(result.getContent().equals("test2")).isTrue()) .verifyComplete(); @@ -153,8 +152,8 @@ public void verifyMultipleWritesInTransactionWithTimeout() { @Test public void verifyMultipleWritesInTransactionWithTimeoutExpired() { // Multi-record transactions are supported starting with Server version 8.0+ - SampleClasses.DocumentWithIntegerId document1 = new SampleClasses.DocumentWithIntegerId(501, "test1"); - SampleClasses.DocumentWithIntegerId document2 = new SampleClasses.DocumentWithIntegerId(501, "test2"); + SampleClasses.DocumentWithIntegerId document1 = new SampleClasses.DocumentWithIntegerId(521, "test1"); + SampleClasses.DocumentWithIntegerId document2 = new SampleClasses.DocumentWithIntegerId(521, "test2"); reactiveTemplate.insert(document1) // wait more than the specified timeout for this transactional operator @@ -171,6 +170,27 @@ public void verifyMultipleWritesInTransactionWithTimeoutExpired() { }); } + @Test + public void verifyMultipleWritesInTransactionWithDefaultTimeoutExpired() { + // Multi-record transactions are supported starting with Server version 8.0+ + SampleClasses.DocumentWithIntegerId document1 = new SampleClasses.DocumentWithIntegerId(522, "test1"); + SampleClasses.DocumentWithIntegerId document2 = new SampleClasses.DocumentWithIntegerId(522, "test2"); + + reactiveTemplate.insert(document1) + // wait more than the specified timeout for this transactional operator + .delayElement(Duration.ofSeconds(15)) + .then(reactiveTemplate.save(document2)) + .then() + .as(transactionalOperator::transactional) + .as(StepVerifier::create) + .verifyErrorMatches(throwable -> { + if (throwable instanceof RecoverableDataAccessException) { + return throwable.getMessage().contains("MRT expired"); + } + return false; + }); + } + @Test public void oneWriteInTransaction_manual_transactional() { // Multi-record transactions are supported starting with Server version 8.0+ diff --git a/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionUnitTests.java b/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionUnitTests.java index 0a443a2f..f7878ea9 100644 --- a/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionUnitTests.java +++ b/src/test/java/org/springframework/data/aerospike/transaction/reactive/ReactiveAerospikeTemplateTransactionUnitTests.java @@ -416,7 +416,7 @@ public void nativeSessionSynchronization_verifyTransactionExists() { transactionalOperator .execute(transaction -> forCurrentTransaction() .doOnNext(synchronizationManager -> { - WritePolicy wPolicy = reactorClient.getWritePolicyDefault(); + WritePolicy wPolicy = new WritePolicy(reactorClient.getWritePolicyDefault()); AerospikeReactiveTransactionResourceHolder rHolder = (AerospikeReactiveTransactionResourceHolder) synchronizationManager.getResource(reactorClient); wPolicy.txn = rHolder != null ? rHolder.getTransaction() : null; @@ -451,7 +451,7 @@ public void nativeSessionSynchronization_verifyRollback() { transactionalOperator .execute(transaction -> forCurrentTransaction() .doOnNext(synchronizationManager -> { - WritePolicy wPolicy = reactorClient.getWritePolicyDefault(); + WritePolicy wPolicy = new WritePolicy(reactorClient.getWritePolicyDefault()); AerospikeReactiveTransactionResourceHolder rHolder = (AerospikeReactiveTransactionResourceHolder) synchronizationManager.getResource(reactorClient); wPolicy.txn = rHolder != null ? rHolder.getTransaction() : null; diff --git a/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTemplateTransactionTests.java b/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTemplateTransactionTests.java index d9f95d0c..c3ef548b 100644 --- a/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTemplateTransactionTests.java +++ b/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTemplateTransactionTests.java @@ -145,6 +145,21 @@ public void multipleWritesInTransactionWithTimeoutExpired() { assertThat(result).isNull(); // No record is written because all commands were in the same transaction } + @Test + public void multipleWritesInTransactionWithDefaultTimeoutExpired() { + // Multi-record transactions are supported starting with Server version 8.0+ + assertThatThrownBy(() -> transactionTemplate.executeWithoutResult(status -> { + template.insert(new SampleClasses.DocumentWithIntegerId(124, "test1")); + AwaitilityUtils.wait(15, SECONDS); // timeout expires during this wait + template.save(new SampleClasses.DocumentWithIntegerId(124, "test2")); + })) + .isInstanceOf(RecoverableDataAccessException.class) + .hasMessageContaining("MRT expired"); + + SampleClasses.DocumentWithIntegerId result = template.findById(124, SampleClasses.DocumentWithIntegerId.class); + assertThat(result).isNull(); // No record is written because all commands were in the same transaction + } + @Test // just for testing purposes as performing only one write in a transaction lacks sense public void batchWriteInTransaction() { diff --git a/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTransactionalAnnotationTests.java b/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTransactionalAnnotationTests.java index 7b80d5d6..7fd3c960 100644 --- a/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTransactionalAnnotationTests.java +++ b/src/test/java/org/springframework/data/aerospike/transaction/sync/AerospikeTransactionalAnnotationTests.java @@ -64,6 +64,11 @@ public void afterAll() { SampleClasses.DocumentWithIntegerId.class); } + public void transactional_multipleInserts(Object document1, Object document2) { + template.insert(document1); + template.insert(document2); + } + @Test @Transactional(transactionManager = "aerospikeTransactionManager") @Rollback(value = false) @@ -96,9 +101,14 @@ public void verifyTransactionExists_multipleMethods() { // only for testing purposes as performing one write in a transaction lacks sense public void verifyTransaction_oneInsert() { TestTransactionSynchronization testSync = new TestTransactionSynchronization(() -> { - SampleClasses.DocumentWithPrimitiveIntId result = - template.findById(300, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result.getId()).isEqualTo(300); + var resultsList = + // findAll() is used here because it uses QueryPolicy and ignores transaction id + // it is a callback after transaction completion, typically fast enough to happen before cleanup, + // so de facto transaction id is often still findable at this point + template.findAll(SampleClasses.DocumentWithPrimitiveIntId.class).toList(); + assertThat(resultsList).hasSize(1); + assertThat(resultsList.stream().map(SampleClasses.DocumentWithPrimitiveIntId::getId).toList()) + .containsExactlyInAnyOrder(300); System.out.println("Verified"); }); // Register the action to perform after transaction is completed @@ -113,12 +123,10 @@ public void verifyTransaction_oneInsert() { // just for testing purposes as performing only one write in a transactions lacks sense public void verifyTransaction_batchInsert() { TestTransactionSynchronization testSync = new TestTransactionSynchronization(() -> { - SampleClasses.DocumentWithPrimitiveIntId result1 = - template.findById(301, SampleClasses.DocumentWithPrimitiveIntId.class); - SampleClasses.DocumentWithPrimitiveIntId result2 = - template.findById(401, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result1.getId()).isEqualTo(301); - assertThat(result2.getId()).isEqualTo(401); + var resultsList = template.findAll(SampleClasses.DocumentWithPrimitiveIntId.class).toList(); + assertThat(resultsList).hasSize(2); + assertThat(resultsList.stream().map(SampleClasses.DocumentWithPrimitiveIntId::getId).toList()) + .containsExactlyInAnyOrder(301, 401); System.out.println("Verified"); }); // Register the action to perform after transaction is completed @@ -128,22 +136,15 @@ public void verifyTransaction_batchInsert() { new SampleClasses.DocumentWithPrimitiveIntId(401))); } - public void transactional_multipleInserts(Object document1, Object document2) { - template.insert(document1); - template.insert(document2); - } - @Test @Transactional @Rollback(value = false) public void verifyTransaction_multipleWrites() { TestTransactionSynchronization testSync = new TestTransactionSynchronization(() -> { - SampleClasses.DocumentWithPrimitiveIntId result1 = - template.findById(302, SampleClasses.DocumentWithPrimitiveIntId.class); - SampleClasses.DocumentWithPrimitiveIntId result2 = - template.findById(402, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result1.getId()).isEqualTo(302); - assertThat(result2.getId()).isEqualTo(402); + var resultsList = template.findAll(SampleClasses.DocumentWithPrimitiveIntId.class).toList(); + assertThat(resultsList).hasSize(2); + assertThat(resultsList.stream().map(SampleClasses.DocumentWithPrimitiveIntId::getId).toList()) + .containsExactlyInAnyOrder(302, 402); System.out.println("Verified"); }); // Register the action to perform after transaction is completed @@ -158,12 +159,10 @@ public void verifyTransaction_multipleWrites() { @Rollback(value = false) public void verifyTransaction_multipleInserts_withTimeout() { TestTransactionSynchronization testSync = new TestTransactionSynchronization(() -> { - SampleClasses.DocumentWithPrimitiveIntId result1 = - template.findById(304, SampleClasses.DocumentWithPrimitiveIntId.class); - SampleClasses.DocumentWithPrimitiveIntId result2 = - template.findById(305, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result1.getId()).isEqualTo(304); - assertThat(result2.getId()).isEqualTo(305); + var resultsList = template.findAll(SampleClasses.DocumentWithPrimitiveIntId.class).toList(); + assertThat(resultsList).hasSize(2); + assertThat(resultsList.stream().map(SampleClasses.DocumentWithPrimitiveIntId::getId).toList()) + .containsExactlyInAnyOrder(304, 305); System.out.println("Verified"); }); // Register the action to perform after transaction is completed @@ -190,9 +189,8 @@ public void verifyTransaction_multipleInserts_withTimeoutExpired() { @Rollback() // rollback is set to true to simulate propagating exception that rolls back transaction public void verifyTransaction_multipleWrites_rollback() { TestTransactionSynchronization testSync = new TestTransactionSynchronization(() -> { - SampleClasses.DocumentWithPrimitiveIntId result = - template.findById(303, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result).isNull(); + var resultsList = template.findAll(SampleClasses.DocumentWithPrimitiveIntId.class).toList(); + assertThat(resultsList).hasSize(0); System.out.println("Verified"); }); // Register the action to perform after transaction is completed @@ -210,18 +208,10 @@ public void verifyTransaction_multipleWrites_rollback() { @Rollback(value = false) public void verifyTransaction_multipleBatchInserts_withTimeout() { TestTransactionSynchronization testSync = new TestTransactionSynchronization(() -> { - SampleClasses.DocumentWithPrimitiveIntId result1 = - template.findById(307, SampleClasses.DocumentWithPrimitiveIntId.class); - SampleClasses.DocumentWithPrimitiveIntId result2 = - template.findById(407, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result1.getId()).isEqualTo(307); - assertThat(result2.getId()).isEqualTo(407); - SampleClasses.DocumentWithPrimitiveIntId result3 = - template.findById(308, SampleClasses.DocumentWithPrimitiveIntId.class); - SampleClasses.DocumentWithPrimitiveIntId result4 = - template.findById(408, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result3.getId()).isEqualTo(308); - assertThat(result4.getId()).isEqualTo(408); + var resultsList = template.findAll(SampleClasses.DocumentWithPrimitiveIntId.class).toList(); + assertThat(resultsList).hasSize(4); + assertThat(resultsList.stream().map(SampleClasses.DocumentWithPrimitiveIntId::getId).toList()) + .containsExactlyInAnyOrder(307, 407, 308, 408); System.out.println("Verified"); }); // Register the action to perform after transaction is completed @@ -255,9 +245,8 @@ public void verifyTransaction_multipleBatchInserts_withTimeoutExpired() { // only for testing purposes as performing one write in a transaction lacks sense public void verifyTransaction_oneDelete() { TestTransactionSynchronization testSync = new TestTransactionSynchronization(() -> { - SampleClasses.DocumentWithPrimitiveIntId result = - template.findById(1004, SampleClasses.DocumentWithPrimitiveIntId.class); - assertThat(result.getId()).isNull(); + var resultsList = template.findAll(SampleClasses.DocumentWithPrimitiveIntId.class).toList(); + assertThat(resultsList).hasSize(0); System.out.println("Verified"); }); // Register the action to perform after transaction is completed