diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLExceptionSubclassTranslator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLExceptionSubclassTranslator.java index ef1d9b285ee..bd8e0b9b53c 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLExceptionSubclassTranslator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLExceptionSubclassTranslator.java @@ -80,43 +80,43 @@ public class SQLExceptionSubclassTranslator extends AbstractFallbackSQLException if (sqlEx instanceof SQLTransientException) { if (sqlEx instanceof SQLTransientConnectionException) { - return new TransientDataAccessResourceException(buildMessage(task, sql, sqlEx), sqlEx); + return new TransientDataAccessResourceException(buildMessage(task, sql, sqlEx), ex); } if (sqlEx instanceof SQLTransactionRollbackException) { if (SQLStateSQLExceptionTranslator.indicatesCannotAcquireLock(sqlEx.getSQLState())) { - return new CannotAcquireLockException(buildMessage(task, sql, sqlEx), sqlEx); + return new CannotAcquireLockException(buildMessage(task, sql, sqlEx), ex); } - return new PessimisticLockingFailureException(buildMessage(task, sql, sqlEx), sqlEx); + return new PessimisticLockingFailureException(buildMessage(task, sql, sqlEx), ex); } if (sqlEx instanceof SQLTimeoutException) { - return new QueryTimeoutException(buildMessage(task, sql, sqlEx), sqlEx); + return new QueryTimeoutException(buildMessage(task, sql, sqlEx), ex); } } else if (sqlEx instanceof SQLNonTransientException) { if (sqlEx instanceof SQLNonTransientConnectionException) { - return new DataAccessResourceFailureException(buildMessage(task, sql, sqlEx), sqlEx); + return new DataAccessResourceFailureException(buildMessage(task, sql, sqlEx), ex); } if (sqlEx instanceof SQLDataException) { - return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), sqlEx); + return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), ex); } if (sqlEx instanceof SQLIntegrityConstraintViolationException) { if (SQLStateSQLExceptionTranslator.indicatesDuplicateKey(sqlEx.getSQLState(), sqlEx.getErrorCode())) { - return new DuplicateKeyException(buildMessage(task, sql, sqlEx), sqlEx); + return new DuplicateKeyException(buildMessage(task, sql, sqlEx), ex); } - return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), sqlEx); + return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), ex); } if (sqlEx instanceof SQLInvalidAuthorizationSpecException) { - return new PermissionDeniedDataAccessException(buildMessage(task, sql, sqlEx), sqlEx); + return new PermissionDeniedDataAccessException(buildMessage(task, sql, sqlEx), ex); } if (sqlEx instanceof SQLSyntaxErrorException) { - return new BadSqlGrammarException(task, (sql != null ? sql : ""), sqlEx); + return new BadSqlGrammarException(task, (sql != null ? sql : ""), ex); } if (sqlEx instanceof SQLFeatureNotSupportedException) { - return new InvalidDataAccessApiUsageException(buildMessage(task, sql, sqlEx), sqlEx); + return new InvalidDataAccessApiUsageException(buildMessage(task, sql, sqlEx), ex); } } else if (sqlEx instanceof SQLRecoverableException) { - return new RecoverableDataAccessException(buildMessage(task, sql, sqlEx), sqlEx); + return new RecoverableDataAccessException(buildMessage(task, sql, sqlEx), ex); } // Fallback to Spring's own SQL state translation... diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java index e00c8d3a0e2..d1f2f0d814a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java @@ -131,35 +131,35 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException logger.debug("Extracted SQL state class '" + classCode + "' from value '" + sqlState + "'"); } if (BAD_SQL_GRAMMAR_CODES.contains(classCode)) { - return new BadSqlGrammarException(task, (sql != null ? sql : ""), sqlEx); + return new BadSqlGrammarException(task, (sql != null ? sql : ""), ex); } else if (DATA_INTEGRITY_VIOLATION_CODES.contains(classCode)) { if (indicatesDuplicateKey(sqlState, sqlEx.getErrorCode())) { - return new DuplicateKeyException(buildMessage(task, sql, sqlEx), sqlEx); + return new DuplicateKeyException(buildMessage(task, sql, sqlEx), ex); } - return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), sqlEx); + return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), ex); } else if (PESSIMISTIC_LOCKING_FAILURE_CODES.contains(classCode)) { if (indicatesCannotAcquireLock(sqlState)) { - return new CannotAcquireLockException(buildMessage(task, sql, sqlEx), sqlEx); + return new CannotAcquireLockException(buildMessage(task, sql, sqlEx), ex); } - return new PessimisticLockingFailureException(buildMessage(task, sql, sqlEx), sqlEx); + return new PessimisticLockingFailureException(buildMessage(task, sql, sqlEx), ex); } else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) { if (indicatesQueryTimeout(sqlState)) { - return new QueryTimeoutException(buildMessage(task, sql, sqlEx), sqlEx); + return new QueryTimeoutException(buildMessage(task, sql, sqlEx), ex); } - return new DataAccessResourceFailureException(buildMessage(task, sql, sqlEx), sqlEx); + return new DataAccessResourceFailureException(buildMessage(task, sql, sqlEx), ex); } else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) { - return new TransientDataAccessResourceException(buildMessage(task, sql, sqlEx), sqlEx); + return new TransientDataAccessResourceException(buildMessage(task, sql, sqlEx), ex); } } // For MySQL: exception class name indicating a timeout? // (since MySQL doesn't throw the JDBC 4 SQLTimeoutException) if (sqlEx.getClass().getName().contains("Timeout")) { - return new QueryTimeoutException(buildMessage(task, sql, sqlEx), sqlEx); + return new QueryTimeoutException(buildMessage(task, sql, sqlEx), ex); } // Couldn't resolve anything proper - resort to UncategorizedSQLException. diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java index 3662789f6f7..6abb423bbc0 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java @@ -181,8 +181,7 @@ class SQLStateSQLExceptionTranslatorTests { static void assertTranslation(DataAccessException dae, SQLException ex, Class dataAccessExceptionType) { assertThat(dae).as("Specific translation must not result in null").isNotNull(); assertThat(dae).as("Wrong DataAccessException type returned").isExactlyInstanceOf(dataAccessExceptionType); - assertThat(dae.getCause()).as("The exact same original SQLException must be preserved").isSameAs( - ex instanceof BatchUpdateException bue ? bue.getNextException() : ex); + assertThat(dae.getCause()).as("The exact same original SQLException must be preserved").isSameAs(ex); } static BatchUpdateException buildBatchUpdateException(@Nullable String sqlState, SQLException next) {