Translate CasMismatchException to OptimisticLockingFailureException. (#1341)
Translate CasMismatchException to OptimisticLockingFailureException instead of DataIntegrityViolationException. CasMismatchException is a ConcurrencyFailureException which is a TransientDataAccessException. Versus DataIntegrityViolation, which is a NonTransientDataAccessException. Closed #1339.
This commit is contained in:
@@ -375,7 +375,7 @@ public class User {
|
||||
|
||||
If you load a document through the template or repository, the version field will be automatically populated with the current CAS value.
|
||||
It is important to note that you shouldn't access the field or even change it on your own.
|
||||
Once you save the document back, it will either succeed or fail with a `DataIntegrityViolationException`.
|
||||
Once you save the document back, it will either succeed or fail with a `OptimisticLockingFailureException`.
|
||||
If you get such an exception, the further approach depends on what you want to achieve application wise.
|
||||
You should either retry the complete load-update-write cycle or propagate the error to the upper layers for proper handling.
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;;
|
||||
import org.springframework.dao.QueryTimeoutException;
|
||||
import org.springframework.dao.TransientDataAccessResourceException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
@@ -66,8 +67,11 @@ public class CouchbaseExceptionTranslator implements PersistenceExceptionTransla
|
||||
return new DataRetrievalFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
if (ex instanceof CasMismatchException || ex instanceof ConcurrentModificationException
|
||||
|| ex instanceof ReplicaNotConfiguredException || ex instanceof DurabilityLevelNotAvailableException
|
||||
if (ex instanceof CasMismatchException || ex instanceof ConcurrentModificationException) {
|
||||
return new OptimisticLockingFailureException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
if ( ex instanceof ReplicaNotConfiguredException || ex instanceof DurabilityLevelNotAvailableException
|
||||
|| ex instanceof DurabilityImpossibleException || ex instanceof DurabilityAmbiguousException) {
|
||||
return new DataIntegrityViolationException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByIdOperation.ExecutableFindById;
|
||||
import org.springframework.data.couchbase.core.ExecutableRemoveByIdOperation.ExecutableRemoveById;
|
||||
import org.springframework.data.couchbase.core.ExecutableReplaceByIdOperation.ExecutableReplaceById;
|
||||
@@ -137,7 +138,7 @@ class CouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationTests {
|
||||
|
||||
User badUser = new User(user.getId(), user.getFirstname(), user.getLastname());
|
||||
badUser.setVersion(12345678);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> couchbaseTemplate.replaceById(User.class).one(badUser));
|
||||
assertThrows(OptimisticLockingFailureException.class, () -> couchbaseTemplate.replaceById(User.class).one(badUser));
|
||||
|
||||
User found = couchbaseTemplate.findById(User.class).one(user.getId());
|
||||
assertEquals(modified, found);
|
||||
@@ -347,7 +348,7 @@ class CouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationTests {
|
||||
// careful now - user and modified are the same object. The object has the new cas (@Version version)
|
||||
Long savedCas = modified.getVersion();
|
||||
modified.setVersion(123);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> couchbaseTemplate.removeById()
|
||||
assertThrows(OptimisticLockingFailureException.class, () -> couchbaseTemplate.removeById()
|
||||
.withCas(reactiveCouchbaseTemplate.support().getCas(modified)).one(modified.getId()));
|
||||
modified.setVersion(savedCas);
|
||||
couchbaseTemplate.removeById().withCas(reactiveCouchbaseTemplate.support().getCas(modified))
|
||||
|
||||
@@ -37,8 +37,8 @@ import java.util.UUID;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.couchbase.core.ReactiveFindByIdOperation.ReactiveFindById;
|
||||
import org.springframework.data.couchbase.core.ReactiveRemoveByIdOperation.ReactiveRemoveById;
|
||||
import org.springframework.data.couchbase.core.ReactiveReplaceByIdOperation.ReactiveReplaceById;
|
||||
@@ -130,7 +130,7 @@ class ReactiveCouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationT
|
||||
|
||||
User badUser = new User(user.getId(), user.getFirstname(), user.getLastname());
|
||||
badUser.setVersion(12345678);
|
||||
assertThrows(DataIntegrityViolationException.class,
|
||||
assertThrows(OptimisticLockingFailureException.class,
|
||||
() -> reactiveCouchbaseTemplate.replaceById(User.class).one(badUser).block());
|
||||
|
||||
User found = reactiveCouchbaseTemplate.findById(User.class).one(user.getId()).block();
|
||||
@@ -285,7 +285,7 @@ class ReactiveCouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationT
|
||||
// careful now - user and modified are the same object. The object has the new cas (@Version version)
|
||||
Long savedCas = modified.getVersion();
|
||||
modified.setVersion(123);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> reactiveCouchbaseTemplate.removeById()
|
||||
assertThrows(OptimisticLockingFailureException.class, () -> reactiveCouchbaseTemplate.removeById()
|
||||
.withCas(reactiveCouchbaseTemplate.support().getCas(modified)).one(modified.getId()).block());
|
||||
modified.setVersion(savedCas);
|
||||
reactiveCouchbaseTemplate.removeById().withCas(reactiveCouchbaseTemplate.support().getCas(modified))
|
||||
|
||||
@@ -36,8 +36,8 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.data.couchbase.domain.Airline;
|
||||
@@ -111,7 +111,7 @@ public class CouchbaseRepositoryKeyValueIntegrationTests extends ClusterAwareInt
|
||||
user.setVersion(0);
|
||||
assertThrows(DuplicateKeyException.class, () -> userRepository.save(user));
|
||||
user.setVersion(saveVersion + 1);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> userRepository.save(user));
|
||||
assertThrows(OptimisticLockingFailureException.class, () -> userRepository.save(user));
|
||||
userRepository.delete(user);
|
||||
|
||||
// Airline does not have a version
|
||||
|
||||
@@ -55,8 +55,8 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.auditing.DateTimeProvider;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
@@ -566,7 +566,7 @@ public class CouchbaseRepositoryQueryIntegrationTests extends ClusterAwareIntegr
|
||||
userRepository.save(user);
|
||||
long saveVersion = user.getVersion();
|
||||
user.setVersion(user.getVersion() - 1);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> userRepository.save(user));
|
||||
assertThrows(OptimisticLockingFailureException.class, () -> userRepository.save(user));
|
||||
user.setVersion(saveVersion);
|
||||
userRepository.save(user);
|
||||
userRepository.delete(user);
|
||||
|
||||
@@ -28,8 +28,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.auditing.DateTimeProvider;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.domain.Airline;
|
||||
@@ -72,7 +72,7 @@ public class ReactiveCouchbaseRepositoryKeyValueIntegrationTests extends Cluster
|
||||
user.setVersion(0);
|
||||
assertThrows(DuplicateKeyException.class, () -> userRepository.save(user).block());
|
||||
user.setVersion(saveVersion + 1);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> userRepository.save(user).block());
|
||||
assertThrows(OptimisticLockingFailureException.class, () -> userRepository.save(user).block());
|
||||
userRepository.delete(user);
|
||||
|
||||
// Airline does not have a version
|
||||
|
||||
@@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
@@ -40,7 +41,6 @@ import java.util.stream.Collectors;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
import org.springframework.data.couchbase.CouchbaseClientFactory;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
@@ -120,7 +120,7 @@ public class ReactiveCouchbaseRepositoryQueryIntegrationTests extends JavaIntegr
|
||||
userRepository.save(user).block();
|
||||
long saveVersion = user.getVersion();
|
||||
user.setVersion(user.getVersion() - 1);
|
||||
assertThrows(DataIntegrityViolationException.class, () -> userRepository.save(user).block());
|
||||
assertThrows(OptimisticLockingFailureException.class, () -> userRepository.save(user).block());
|
||||
user.setVersion(saveVersion);
|
||||
userRepository.save(user).block();
|
||||
userRepository.delete(user).block();
|
||||
|
||||
Reference in New Issue
Block a user