Skip to content

Commit b44833b

Browse files
committed
HHH-18772 introduce AuthException and simplify SQLStateConversionDelegate
Signed-off-by: Gavin King <[email protected]>
1 parent 55255e9 commit b44833b

File tree

4 files changed

+90
-81
lines changed

4 files changed

+90
-81
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
/**
12+
* A {@link JDBCException} indicating an authentication or authorization failure.
13+
*
14+
* @since 7.0
15+
*
16+
* @author Gavin King
17+
*/
18+
public class AuthException extends JDBCException {
19+
/**
20+
* Constructor for AuthException.
21+
*
22+
* @param root The underlying exception.
23+
*/
24+
public AuthException(String message, SQLException root) {
25+
super( message, root );
26+
}
27+
28+
/**
29+
* Constructor for AuthException.
30+
*
31+
* @param message Optional message.
32+
* @param root The underlying exception.
33+
*/
34+
public AuthException(String message, SQLException root, String sql) {
35+
super( message, root, sql );
36+
}
37+
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
import org.hibernate.JDBCException;
1010

1111
/**
12-
* Extends {@link JDBCException} indicating that evaluation of the
12+
* A {@link JDBCException} indicating that evaluation of the
1313
* valid SQL statement against the given data resulted in some
1414
* illegal operation, mismatched types or incorrect cardinality.
1515
*
1616
* @author Gavin King
1717
*/
1818
public class DataException extends JDBCException {
1919
/**
20-
* Constructor for JDBCException.
20+
* Constructor for DataException.
2121
*
2222
* @param root The underlying exception.
2323
*/
@@ -26,7 +26,7 @@ public DataException(String message, SQLException root) {
2626
}
2727

2828
/**
29-
* Constructor for JDBCException.
29+
* Constructor for DataException.
3030
*
3131
* @param message Optional message.
3232
* @param root The underlying exception.

hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java

Lines changed: 49 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -5,120 +5,95 @@
55
package org.hibernate.exception.internal;
66

77
import java.sql.SQLException;
8-
import java.util.Set;
98

109
import org.hibernate.JDBCException;
1110
import org.hibernate.PessimisticLockException;
1211
import org.hibernate.QueryTimeoutException;
12+
import org.hibernate.exception.AuthException;
1313
import org.hibernate.exception.ConstraintViolationException;
1414
import org.hibernate.exception.DataException;
1515
import org.hibernate.exception.JDBCConnectionException;
1616
import org.hibernate.exception.LockAcquisitionException;
1717
import org.hibernate.exception.SQLGrammarException;
1818
import org.hibernate.exception.spi.AbstractSQLExceptionConversionDelegate;
1919
import org.hibernate.exception.spi.ConversionContext;
20-
import org.hibernate.internal.util.JdbcExceptionHelper;
2120

2221
import org.checkerframework.checker.nullness.qual.Nullable;
2322

23+
import static org.hibernate.internal.util.JdbcExceptionHelper.determineSqlStateClassCode;
24+
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
25+
import static org.hibernate.internal.util.JdbcExceptionHelper.extractSqlState;
26+
2427
/**
2528
* A {@link org.hibernate.exception.spi.SQLExceptionConverter} implementation which performs conversion based
2629
* on the underlying SQLState. Interpretation of a SQL error based on SQLState is not nearly as accurate as
2730
* using the ErrorCode (which is, however, vendor-specific).
28-
* <p>
29-
* SQLState codes are defined by both ANSI SQL specs and X/Open. Some "classes" are shared, others are
30-
* specific to one or another, yet others are custom vendor classes. Unfortunately I have not been able to
31-
* find a "blessed" list of X/Open codes. These codes are cobbled together between ANSI SQL spec and error
31+
*
32+
* @implNote
33+
* SQLState codes are defined by both ANSI SQL specs and X/Open. Some "classes" are shared, others are
34+
* specific to one or another, yet others are custom vendor classes. Unfortunately I have not been able to
35+
* find a "blessed" list of X/Open codes. These codes are cobbled together between ANSI SQL spec and error
3236
* code tables from few vendor's documentation.
3337
*
3438
* @author Steve Ebersole
3539
*/
3640
public class SQLStateConversionDelegate extends AbstractSQLExceptionConversionDelegate {
3741

38-
private static final Set<String> SQL_GRAMMAR_CATEGORIES = buildGrammarCategories();
39-
private static Set<String> buildGrammarCategories() {
40-
return Set.of(
41-
"07", // "dynamic SQL error"
42-
"20",
43-
"2A", // "direct SQL syntax error or access rule violation"
44-
"37", // "dynamic SQL syntax error or access rule violation"
45-
"42", // "syntax error or access rule violation"
46-
"65", // Oracle specific as far as I can tell
47-
"S0" // MySQL specific as far as I can tell
48-
);
49-
}
50-
51-
private static final Set<String> DATA_CATEGORIES = buildDataCategories();
52-
private static Set<String> buildDataCategories() {
53-
return Set.of(
54-
"21", // "cardinality violation"
55-
"22" // "data exception"
56-
);
57-
}
58-
59-
private static final Set<String> INTEGRITY_VIOLATION_CATEGORIES = buildContraintCategories();
60-
private static Set<String> buildContraintCategories() {
61-
return Set.of(
62-
"23", // "integrity constraint violation"
63-
"27", // "triggered data change violation"
64-
"44" // "with check option violation"
65-
);
66-
}
67-
68-
private static final Set<String> CONNECTION_CATEGORIES = buildConnectionCategories();
69-
private static Set<String> buildConnectionCategories() {
70-
return Set.of(
71-
"08" // "connection exception"
72-
);
73-
}
74-
7542
public SQLStateConversionDelegate(ConversionContext conversionContext) {
7643
super( conversionContext );
7744
}
7845

7946
@Override
8047
public @Nullable JDBCException convert(SQLException sqlException, String message, String sql) {
81-
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
82-
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
83-
48+
final String sqlState = extractSqlState( sqlException );
8449
if ( sqlState != null ) {
85-
String sqlStateClassCode = JdbcExceptionHelper.determineSqlStateClassCode( sqlState );
86-
87-
if ( sqlStateClassCode != null ) {
88-
if ( SQL_GRAMMAR_CATEGORIES.contains( sqlStateClassCode ) ) {
50+
switch ( sqlState ) {
51+
case "42501":
52+
return new AuthException( message, sqlException, sql );
53+
case "40001":
54+
return new LockAcquisitionException( message, sqlException, sql );
55+
case "40XL1", "40XL2":
56+
// Derby "A lock could not be obtained within the time requested."
57+
return new PessimisticLockException( message, sqlException, sql );
58+
case "70100":
59+
// MySQL Query execution was interrupted
60+
return new QueryTimeoutException( message, sqlException, sql );
61+
case "72000":
62+
if ( extractErrorCode( sqlException ) == 1013 ) {
63+
// Oracle user requested cancel of current operation
64+
return new QueryTimeoutException( message, sqlException, sql );
65+
}
66+
}
67+
switch ( determineSqlStateClassCode( sqlState ) ) {
68+
case
69+
"07", // "dynamic SQL error"
70+
"20",
71+
"2A", // "direct SQL syntax error or access rule violation"
72+
"37", // "dynamic SQL syntax error or access rule violation"
73+
"42", // "syntax error or access rule violation"
74+
"65", // Oracle specific as far as I can tell
75+
"S0": // MySQL specific as far as I can tell
8976
return new SQLGrammarException( message, sqlException, sql );
90-
}
91-
else if ( INTEGRITY_VIOLATION_CATEGORIES.contains( sqlStateClassCode ) ) {
77+
case
78+
"23", // "integrity constraint violation"
79+
"27", // "triggered data change violation"
80+
"44": // "with check option violation"
9281
final String constraintName = getConversionContext()
9382
.getViolatedConstraintNameExtractor()
9483
.extractConstraintName( sqlException );
9584
return new ConstraintViolationException( message, sqlException, sql, constraintName );
96-
}
97-
else if ( CONNECTION_CATEGORIES.contains( sqlStateClassCode ) ) {
85+
case
86+
"08": // "connection exception"
9887
return new JDBCConnectionException( message, sqlException, sql );
99-
}
100-
else if ( DATA_CATEGORIES.contains( sqlStateClassCode ) ) {
88+
case
89+
"21", // "cardinality violation"
90+
"22": // "data exception"
10191
return new DataException( message, sqlException, sql );
102-
}
103-
}
104-
105-
if ( "40001".equals( sqlState ) ) {
106-
return new LockAcquisitionException( message, sqlException, sql );
107-
}
108-
109-
if ( "40XL1".equals( sqlState ) || "40XL2".equals( sqlState )) {
110-
// Derby "A lock could not be obtained within the time requested."
111-
return new PessimisticLockException( message, sqlException, sql );
112-
}
113-
114-
// MySQL Query execution was interrupted
115-
if ( "70100".equals( sqlState ) ||
116-
// Oracle user requested cancel of current operation
117-
( "72000".equals( sqlState ) && errorCode == 1013 ) ) {
118-
return new QueryTimeoutException( message, sqlException, sql );
92+
case
93+
"28": // "authentication failure"
94+
return new AuthException( message, sqlException, sql );
11995
}
12096
}
121-
12297
return null;
12398
}
12499
}

hibernate-core/src/main/java/org/hibernate/internal/util/JdbcExceptionHelper.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ public static String extractSqlStateClassCode(SQLException sqlException) {
5656
}
5757

5858
public static String determineSqlStateClassCode(String sqlState) {
59-
if ( sqlState == null || sqlState.length() < 2 ) {
60-
return sqlState;
61-
}
62-
return sqlState.substring( 0, 2 );
59+
return sqlState == null || sqlState.length() < 2 ? sqlState : sqlState.substring( 0, 2 );
6360
}
6461
}

0 commit comments

Comments
 (0)