Skip to content

Commit 47c0c49

Browse files
committed
sync impl of error interpretation on Cockroach and Postgres
this code is basically a copy/paste job so lets keep it that way
1 parent f7e0446 commit 47c0c49

File tree

3 files changed

+51
-55
lines changed

3 files changed

+51
-55
lines changed

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

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.checkerframework.checker.nullness.qual.Nullable;
2222
import org.hibernate.LockMode;
2323
import org.hibernate.LockOptions;
24-
import org.hibernate.PessimisticLockException;
2524
import org.hibernate.QueryTimeoutException;
2625
import org.hibernate.boot.model.FunctionContributions;
2726
import org.hibernate.boot.model.TypeContributions;
@@ -43,6 +42,7 @@
4342
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
4443
import org.hibernate.engine.spi.SessionFactoryImplementor;
4544
import org.hibernate.exception.LockAcquisitionException;
45+
import org.hibernate.exception.LockTimeoutException;
4646
import org.hibernate.exception.TransactionSerializationException;
4747
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
4848
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor;
@@ -1063,21 +1063,13 @@ public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
10631063
private static final ViolatedConstraintNameExtractor EXTRACTOR =
10641064
new TemplatedViolatedConstraintNameExtractor( sqle -> {
10651065
final String sqlState = extractSqlState( sqle );
1066-
if ( sqlState == null ) {
1067-
return null;
1068-
}
1069-
return switch ( parseInt( sqlState ) ) {
1070-
// CHECK VIOLATION
1071-
case 23514 -> extractUsingTemplate( "violates check constraint \"", "\"", sqle.getMessage() );
1072-
// UNIQUE VIOLATION
1073-
case 23505 -> extractUsingTemplate(" violates unique constraint \"", "\"", sqle.getMessage() );
1074-
// FOREIGN KEY VIOLATION
1075-
case 23503 -> extractUsingTemplate( "violates foreign key constraint \"", "\"", sqle.getMessage() );
1076-
// NOT NULL VIOLATION
1077-
case 23502 -> extractUsingTemplate( "null value in column \"", "\" violates not-null constraint", sqle.getMessage() );
1078-
// TODO: RESTRICT VIOLATION
1079-
case 23001 -> null;
1080-
// ALL OTHER
1066+
return sqlState == null ? null : switch ( parseInt( sqlState ) ) {
1067+
case 23505, 23514, 23503 ->
1068+
// UNIQUE, CHECK, OR FOREIGN KEY VIOLATION
1069+
extractUsingTemplate( "constraint \"", "\"", sqle.getMessage() );
1070+
case 23502 ->
1071+
// NOT NULL VIOLATION
1072+
extractUsingTemplate( "column \"", "\"", sqle.getMessage() );
10811073
default -> null;
10821074
};
10831075
} );
@@ -1086,19 +1078,22 @@ public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
10861078
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
10871079
return (sqlException, message, sql) -> {
10881080
final String sqlState = extractSqlState( sqlException );
1089-
if ( sqlState == null ) {
1090-
return null;
1091-
}
1092-
return switch (sqlState) {
1093-
// Serialization Exception
1094-
case "40001" -> message.contains("WriteTooOldError")
1095-
? new TransactionSerializationException( message, sqlException, sql )
1096-
: null;
1097-
// DEADLOCK DETECTED
1098-
case "40P01" -> new LockAcquisitionException( message, sqlException, sql );
1099-
// LOCK NOT AVAILABLE
1100-
case "55P03" -> new PessimisticLockException( message, sqlException, sql );
1101-
case "57014" -> new QueryTimeoutException( message, sqlException, sql );
1081+
return sqlState == null ? null : switch ( sqlState ) {
1082+
case "40001" ->
1083+
message.contains( "WriteTooOldError" ) // Serialization Exception
1084+
? new TransactionSerializationException( message, sqlException, sql )
1085+
: null;
1086+
case "40P01" ->
1087+
// DEADLOCK DETECTED
1088+
new LockAcquisitionException( message, sqlException, sql );
1089+
case "55P03" ->
1090+
// LOCK NOT AVAILABLE
1091+
//TODO: should we check that the message is "canceling statement due to lock timeout"
1092+
// and return LockAcquisitionException if it is not?
1093+
new LockTimeoutException( message, sqlException, sql );
1094+
case "57014" ->
1095+
// QUERY CANCELLED
1096+
new QueryTimeoutException( message, sqlException, sql );
11021097
// returning null allows other delegates to operate
11031098
default -> null;
11041099
};

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

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,37 +1021,35 @@ public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
10211021
private static final ViolatedConstraintNameExtractor EXTRACTOR =
10221022
new TemplatedViolatedConstraintNameExtractor( sqle -> {
10231023
final String sqlState = extractSqlState( sqle );
1024-
if ( sqlState != null ) {
1025-
return switch ( parseInt( sqlState ) ) {
1026-
case 23505, 23514, 23503 ->
1027-
// UNIQUE, CHECK, OR FOREIGN KEY VIOLATION
1028-
extractUsingTemplate( "constraint \"", "\"", sqle.getMessage() );
1029-
case 23502 ->
1030-
// NOT NULL VIOLATION
1031-
extractUsingTemplate( "column \"", "\"", sqle.getMessage() );
1032-
default -> null;
1033-
};
1034-
}
1035-
return null;
1024+
return sqlState == null ? null : switch ( parseInt( sqlState ) ) {
1025+
case 23505, 23514, 23503 ->
1026+
// UNIQUE, CHECK, OR FOREIGN KEY VIOLATION
1027+
extractUsingTemplate( "constraint \"", "\"", sqle.getMessage() );
1028+
case 23502 ->
1029+
// NOT NULL VIOLATION
1030+
extractUsingTemplate( "column \"", "\"", sqle.getMessage() );
1031+
default -> null;
1032+
};
10361033
} );
10371034

10381035
@Override
10391036
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
10401037
return (sqlException, message, sql) -> {
10411038
final String sqlState = extractSqlState( sqlException );
1042-
if ( sqlState != null ) {
1043-
switch ( sqlState ) {
1044-
case "40P01": // DEADLOCK DETECTED
1045-
return new LockAcquisitionException( message, sqlException, sql );
1046-
case "55P03": // LOCK NOT AVAILABLE
1047-
//TODO: should we check that the message is "canceling statement due to lock timeout"
1048-
// and return LockAcquisitionException if it is not?
1049-
return new LockTimeoutException( message, sqlException, sql );
1050-
case "57014": // QUERY CANCELLED
1051-
return new QueryTimeoutException( message, sqlException, sql );
1052-
}
1053-
}
1054-
return null;
1039+
return sqlState == null ? null : switch ( sqlState ) {
1040+
case "40P01" ->
1041+
// DEADLOCK DETECTED
1042+
new LockAcquisitionException( message, sqlException, sql );
1043+
case "55P03" ->
1044+
// LOCK NOT AVAILABLE
1045+
//TODO: should we check that the message is "canceling statement due to lock timeout"
1046+
// and return LockAcquisitionException if it is not?
1047+
new LockTimeoutException( message, sqlException, sql );
1048+
case "57014" ->
1049+
// QUERY CANCELLED
1050+
new QueryTimeoutException( message, sqlException, sql );
1051+
default -> null;
1052+
};
10551053
};
10561054
}
10571055

hibernate-core/src/main/java/org/hibernate/exception/TransactionSerializationException.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
import org.hibernate.JDBCException;
88

99
import java.sql.SQLException;
10+
1011
/**
1112
* 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+
* among all currently-executing transactions
14+
*
15+
* @apiNote At present, this is only used to represent {@code WriteTooOldError} on CockroachDB.
1316
*
1417
* @author Karel Maesen
1518
*/

0 commit comments

Comments
 (0)