Skip to content

Commit b5fb125

Browse files
authored
HHH-18760 - CockroachDB dialect remaps serialization error (hibernate#9152)
1 parent ac74e3b commit b5fb125

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
4343
import org.hibernate.engine.spi.SessionFactoryImplementor;
4444
import org.hibernate.exception.LockAcquisitionException;
45+
import org.hibernate.exception.TransactionSerializationException;
4546
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
4647
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
4748
import org.hibernate.exception.spi.ViolatedConstraintNameExtractor;
@@ -1088,6 +1089,10 @@ public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
10881089
return null;
10891090
}
10901091
return switch (sqlState) {
1092+
// Serialization Exception
1093+
case "40001" -> message.contains("WriteTooOldError")
1094+
? new TransactionSerializationException( message, sqlException, sql )
1095+
: null;
10911096
// DEADLOCK DETECTED
10921097
case "40P01" -> new LockAcquisitionException( message, sqlException, sql );
10931098
// LOCK NOT AVAILABLE
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.exception;
6+
7+
import org.hibernate.JDBCException;
8+
9+
import java.sql.SQLException;
10+
/**
11+
* A {@link JDBCException} indicating a transaction failed because it could not be placed into a serializable ordering
12+
* among all of the currently-executing transactions
13+
*
14+
* @author Karel Maesen
15+
*/
16+
public class TransactionSerializationException extends JDBCException {
17+
public TransactionSerializationException(String message, SQLException cause) {
18+
super( message, cause );
19+
}
20+
21+
public TransactionSerializationException(String message, SQLException cause, String sql) {
22+
super( message, cause, sql );
23+
}
24+
}

hibernate-core/src/main/java/org/hibernate/internal/ExceptionConverterImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.hibernate.engine.spi.ExceptionConverter;
2323
import org.hibernate.engine.spi.SharedSessionContractImplementor;
2424
import org.hibernate.exception.LockAcquisitionException;
25+
import org.hibernate.exception.TransactionSerializationException;
2526
import org.hibernate.loader.MultipleBagFetchException;
2627
import org.hibernate.query.IllegalQueryOperationException;
2728
import org.hibernate.query.SemanticException;
@@ -139,6 +140,11 @@ else if ( exception instanceof TransientObjectException ) {
139140
//Spec 3.2.3 Synchronization rules
140141
return new IllegalStateException( exception );
141142
}
143+
else if ( exception instanceof TransactionSerializationException ) {
144+
final PersistenceException converted = new RollbackException( exception.getMessage(), exception );
145+
rollbackIfNecessary( converted );
146+
return converted;
147+
}
142148
else {
143149
rollbackIfNecessary( exception );
144150
return exception;

hibernate-core/src/test/java/org/hibernate/orm/test/batch/BatchUpdateAndVersionTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
import java.util.List;
1010

1111
import jakarta.persistence.OptimisticLockException;
12+
import jakarta.persistence.RollbackException;
1213
import org.hibernate.StaleObjectStateException;
1314
import org.hibernate.cfg.AvailableSettings;
1415

16+
import org.hibernate.exception.TransactionSerializationException;
1517
import org.hibernate.testing.orm.junit.JiraKey;
1618
import org.hibernate.testing.orm.junit.DomainModel;
1719
import org.hibernate.testing.orm.junit.ServiceRegistry;
@@ -136,6 +138,10 @@ public void testFailedUpdate(SessionFactoryScope scope) {
136138
catch (OptimisticLockException ole) {
137139
assertTrue( ole.getCause() instanceof StaleObjectStateException );
138140
}
141+
//CockroachDB errors with a Serialization Exception
142+
catch (RollbackException rbe) {
143+
assertTrue( rbe.getCause() instanceof TransactionSerializationException );
144+
}
139145
}
140146

141147
@Entity(name = "EntityA")

0 commit comments

Comments
 (0)