HHH-18760 - CockroachDB dialect remaps serialization error (#9152)

This commit is contained in:
Karel Maesen 2024-10-29 10:40:02 +01:00 committed by GitHub
parent ac74e3b4e7
commit b5fb125425
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 41 additions and 0 deletions

View File

@ -42,6 +42,7 @@ import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport; import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.exception.LockAcquisitionException; import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.TransactionSerializationException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate; import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor; import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor; import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
@ -1088,6 +1089,10 @@ public class CockroachDialect extends Dialect {
return null; return null;
} }
return switch (sqlState) { return switch (sqlState) {
// Serialization Exception
case "40001" -> message.contains("WriteTooOldError")
? new TransactionSerializationException( message, sqlException, sql )
: null;
// DEADLOCK DETECTED // DEADLOCK DETECTED
case "40P01" -> new LockAcquisitionException( message, sqlException, sql ); case "40P01" -> new LockAcquisitionException( message, sqlException, sql );
// LOCK NOT AVAILABLE // LOCK NOT AVAILABLE

View File

@ -0,0 +1,24 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.exception;
import org.hibernate.JDBCException;
import java.sql.SQLException;
/**
* A {@link JDBCException} indicating a transaction failed because it could not be placed into a serializable ordering
* among all of the currently-executing transactions
*
* @author Karel Maesen
*/
public class TransactionSerializationException extends JDBCException {
public TransactionSerializationException(String message, SQLException cause) {
super( message, cause );
}
public TransactionSerializationException(String message, SQLException cause, String sql) {
super( message, cause, sql );
}
}

View File

@ -22,6 +22,7 @@ import org.hibernate.dialect.lock.PessimisticEntityLockException;
import org.hibernate.engine.spi.ExceptionConverter; import org.hibernate.engine.spi.ExceptionConverter;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.exception.LockAcquisitionException; import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.TransactionSerializationException;
import org.hibernate.loader.MultipleBagFetchException; import org.hibernate.loader.MultipleBagFetchException;
import org.hibernate.query.IllegalQueryOperationException; import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.query.SemanticException; import org.hibernate.query.SemanticException;
@ -139,6 +140,11 @@ public class ExceptionConverterImpl implements ExceptionConverter {
//Spec 3.2.3 Synchronization rules //Spec 3.2.3 Synchronization rules
return new IllegalStateException( exception ); return new IllegalStateException( exception );
} }
else if ( exception instanceof TransactionSerializationException ) {
final PersistenceException converted = new RollbackException( exception.getMessage(), exception );
rollbackIfNecessary( converted );
return converted;
}
else { else {
rollbackIfNecessary( exception ); rollbackIfNecessary( exception );
return exception; return exception;

View File

@ -9,9 +9,11 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import jakarta.persistence.OptimisticLockException; import jakarta.persistence.OptimisticLockException;
import jakarta.persistence.RollbackException;
import org.hibernate.StaleObjectStateException; import org.hibernate.StaleObjectStateException;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.exception.TransactionSerializationException;
import org.hibernate.testing.orm.junit.JiraKey; import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.ServiceRegistry;
@ -136,6 +138,10 @@ public class BatchUpdateAndVersionTest {
catch (OptimisticLockException ole) { catch (OptimisticLockException ole) {
assertTrue( ole.getCause() instanceof StaleObjectStateException ); assertTrue( ole.getCause() instanceof StaleObjectStateException );
} }
//CockroachDB errors with a Serialization Exception
catch (RollbackException rbe) {
assertTrue( rbe.getCause() instanceof TransactionSerializationException );
}
} }
@Entity(name = "EntityA") @Entity(name = "EntityA")