SQLErrorCodeSQLExceptionTranslator tries to find SQLException with actual error code, looping through the causes.
Issue: SPR-10260
This commit is contained in:
parent
188a11bdb9
commit
8a4ce142c4
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,7 +20,6 @@ import java.lang.reflect.Constructor;
|
|||
import java.sql.BatchUpdateException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.core.JdkVersion;
|
||||
|
@ -30,9 +29,9 @@ import org.springframework.dao.DataAccessException;
|
|||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DeadlockLoserDataAccessException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.PermissionDeniedDataAccessException;
|
||||
import org.springframework.dao.TransientDataAccessResourceException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.InvalidResultSetAccessException;
|
||||
|
||||
|
@ -201,20 +200,25 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
|||
|
||||
// Check SQLErrorCodes with corresponding error code, if available.
|
||||
if (this.sqlErrorCodes != null) {
|
||||
String errorCode = null;
|
||||
String errorCode;
|
||||
if (this.sqlErrorCodes.isUseSqlStateForTranslation()) {
|
||||
errorCode = sqlEx.getSQLState();
|
||||
}
|
||||
else {
|
||||
errorCode = Integer.toString(sqlEx.getErrorCode());
|
||||
// Try to find SQLException with actual error code, looping through the causes.
|
||||
// E.g. applicable to java.sql.DataTruncation as of JDK 1.6.
|
||||
SQLException current = sqlEx;
|
||||
while (current.getErrorCode() == 0 && current.getCause() instanceof SQLException) {
|
||||
current = (SQLException) current.getCause();
|
||||
}
|
||||
errorCode = Integer.toString(current.getErrorCode());
|
||||
}
|
||||
|
||||
if (errorCode != null) {
|
||||
// Look for defined custom translations first.
|
||||
CustomSQLErrorCodesTranslation[] customTranslations = this.sqlErrorCodes.getCustomTranslations();
|
||||
if (customTranslations != null) {
|
||||
for (int i = 0; i < customTranslations.length; i++) {
|
||||
CustomSQLErrorCodesTranslation customTranslation = customTranslations[i];
|
||||
for (CustomSQLErrorCodesTranslation customTranslation : customTranslations) {
|
||||
if (Arrays.binarySearch(customTranslation.getErrorCodes(), errorCode) >= 0) {
|
||||
if (customTranslation.getExceptionClass() != null) {
|
||||
DataAccessException customException = createCustomException(
|
||||
|
@ -273,7 +277,7 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
|||
|
||||
// We couldn't identify it more precisely - let's hand it over to the SQLState fallback translator.
|
||||
if (logger.isDebugEnabled()) {
|
||||
String codes = null;
|
||||
String codes;
|
||||
if (this.sqlErrorCodes != null && this.sqlErrorCodes.isUseSqlStateForTranslation()) {
|
||||
codes = "SQL state '" + sqlEx.getSQLState() + "', error code '" + sqlEx.getErrorCode();
|
||||
}
|
||||
|
@ -321,8 +325,8 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
|||
try {
|
||||
int constructorType = 0;
|
||||
Constructor[] constructors = exceptionClass.getConstructors();
|
||||
for (int i = 0; i < constructors.length; i++) {
|
||||
Class[] parameterTypes = constructors[i].getParameterTypes();
|
||||
for (Constructor constructor : constructors) {
|
||||
Class[] parameterTypes = constructor.getParameterTypes();
|
||||
if (parameterTypes.length == 1 && parameterTypes[0].equals(String.class)) {
|
||||
if (constructorType < MESSAGE_ONLY_CONSTRUCTOR)
|
||||
constructorType = MESSAGE_ONLY_CONSTRUCTOR;
|
||||
|
@ -350,7 +354,7 @@ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExcep
|
|||
}
|
||||
|
||||
// invoke constructor
|
||||
Constructor exceptionConstructor = null;
|
||||
Constructor exceptionConstructor;
|
||||
switch (constructorType) {
|
||||
case MESSAGE_SQL_SQLEX_CONSTRUCTOR:
|
||||
Class[] messageAndSqlAndSqlExArgsClass = new Class[] {String.class, String.class, SQLException.class};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,8 +16,9 @@
|
|||
|
||||
package org.springframework.jdbc.support;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.BatchUpdateException;
|
||||
import java.sql.DataTruncation;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
@ -33,6 +34,7 @@ import org.springframework.jdbc.InvalidResultSetAccessException;
|
|||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class SQLErrorCodeSQLExceptionTranslatorTests extends TestCase {
|
||||
|
||||
|
@ -92,13 +94,21 @@ public class SQLErrorCodeSQLExceptionTranslatorTests extends TestCase {
|
|||
SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES);
|
||||
|
||||
SQLException badSqlEx = new SQLException("", "", 1);
|
||||
BatchUpdateException batchUdateEx = new BatchUpdateException();
|
||||
batchUdateEx.setNextException(badSqlEx);
|
||||
BadSqlGrammarException bsgex = (BadSqlGrammarException) sext.translate("task", "SQL", batchUdateEx);
|
||||
BatchUpdateException batchUpdateEx = new BatchUpdateException();
|
||||
batchUpdateEx.setNextException(badSqlEx);
|
||||
BadSqlGrammarException bsgex = (BadSqlGrammarException) sext.translate("task", "SQL", batchUpdateEx);
|
||||
assertEquals("SQL", bsgex.getSql());
|
||||
assertEquals(badSqlEx, bsgex.getSQLException());
|
||||
}
|
||||
|
||||
public void testDataTruncationTranslation() {
|
||||
SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES);
|
||||
|
||||
SQLException dataAccessEx = new SQLException("", "", 5);
|
||||
DataTruncation dataTruncation = new DataTruncation(1, true, true, 1, 1, dataAccessEx);
|
||||
DataAccessResourceFailureException daex = (DataAccessResourceFailureException) sext.translate("task", "SQL", dataTruncation);
|
||||
assertEquals(dataTruncation, daex.getCause());
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public void testCustomTranslateMethodTranslation() {
|
||||
|
|
Loading…
Reference in New Issue