📄 sqlerrorcodesqlexceptiontranslator.java
字号:
}
else {
errorCode = Integer.toString(sqlEx.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];
if (Arrays.binarySearch(customTranslation.getErrorCodes(), errorCode) >= 0) {
if (customTranslation.getExceptionClass() != null) {
DataAccessException customException = createCustomException(
task, sql, sqlEx, customTranslation.getExceptionClass());
if (customException != null) {
logTranslation(task, sql, sqlEx, true);
return customException;
}
}
}
}
}
// Next, look for grouped error codes.
if (Arrays.binarySearch(this.sqlErrorCodes.getBadSqlGrammarCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new BadSqlGrammarException(task, sql, sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getInvalidResultSetAccessCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new InvalidResultSetAccessException(task, sql, sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getDataAccessResourceFailureCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new DataAccessResourceFailureException(buildMessage(task, sql, sqlEx), sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getDataIntegrityViolationCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getCannotAcquireLockCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new CannotAcquireLockException(buildMessage(task, sql, sqlEx), sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getDeadlockLoserCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new DeadlockLoserDataAccessException(buildMessage(task, sql, sqlEx), sqlEx);
}
else if (Arrays.binarySearch(this.sqlErrorCodes.getCannotSerializeTransactionCodes(), errorCode) >= 0) {
logTranslation(task, sql, sqlEx, false);
return new CannotSerializeTransactionException(buildMessage(task, sql, sqlEx), sqlEx);
}
}
}
// We couldn't identify it more precisely - let's hand it over to the SQLState fallback translator.
if (logger.isDebugEnabled()) {
logger.debug("Unable to translate SQLException with errorCode '" + sqlEx.getErrorCode() +
"', will now try the fallback translator");
}
return this.fallbackTranslator.translate(task, sql, sqlEx);
}
/**
* Build a message String for the given SQLException.
* Called when creating an instance of a generic DataAccessException class.
* @param task readable text describing the task being attempted
* @param sql SQL query or update that caused the problem. May be <code>null</code>.
* @param sqlEx the offending SQLException
* @return the message String to use
*/
protected String buildMessage(String task, String sql, SQLException sqlEx) {
return task + "; SQL [" + sql + "]; " + sqlEx.getMessage();
}
/**
* Subclasses can override this method to attempt a custom mapping from SQLException
* to DataAccessException.
* @param task readable text describing the task being attempted
* @param sql SQL query or update that caused the problem. May be <code>null</code>.
* @param sqlEx the offending SQLException
* @return null if no custom translation was possible, otherwise a DataAccessException
* resulting from custom translation. This exception should include the sqlEx parameter
* as a nested root cause. This implementation always returns null, meaning that
* the translator always falls back to the default error codes.
*/
protected DataAccessException customTranslate(String task, String sql, SQLException sqlEx) {
return null;
}
/**
* Create a custom DataAccessException, based on a given exception
* class from a CustomSQLErrorCodesTranslation definition.
* @param task readable text describing the task being attempted
* @param sql SQL query or update that caused the problem. May be <code>null</code>.
* @param sqlEx the offending SQLException
* @param exceptionClass the exception class to use, as defined in the
* CustomSQLErrorCodesTranslation definition
* @return null if the custom exception could not be created, otherwise
* the resulting DataAccessException. This exception should include the
* sqlEx parameter as a nested root cause.
* @see CustomSQLErrorCodesTranslation#setExceptionClass
*/
protected DataAccessException createCustomException(
String task, String sql, SQLException sqlEx, Class exceptionClass) {
// find appropriate constructor
try {
int constructorType = 0;
Constructor[] constructors = exceptionClass.getConstructors();
for (int i = 0; i < constructors.length; i++) {
Class[] parameterTypes = constructors[i].getParameterTypes();
if (parameterTypes.length == 1 && parameterTypes[0].equals(String.class)) {
if (constructorType < MESSAGE_ONLY_CONSTRUCTOR)
constructorType = MESSAGE_ONLY_CONSTRUCTOR;
}
if (parameterTypes.length == 2 && parameterTypes[0].equals(String.class) &&
parameterTypes[1].equals(Throwable.class)) {
if (constructorType < MESSAGE_THROWABLE_CONSTRUCTOR)
constructorType = MESSAGE_THROWABLE_CONSTRUCTOR;
}
if (parameterTypes.length == 2 && parameterTypes[0].equals(String.class) &&
parameterTypes[1].equals(SQLException.class)) {
if (constructorType < MESSAGE_SQLEX_CONSTRUCTOR)
constructorType = MESSAGE_SQLEX_CONSTRUCTOR;
}
if (parameterTypes.length == 3 && parameterTypes[0].equals(String.class) &&
parameterTypes[1].equals(String.class) && parameterTypes[2].equals(Throwable.class)) {
if (constructorType < MESSAGE_SQL_THROWABLE_CONSTRUCTOR)
constructorType = MESSAGE_SQL_THROWABLE_CONSTRUCTOR;
}
if (parameterTypes.length == 3 && parameterTypes[0].equals(String.class) &&
parameterTypes[1].equals(String.class) && parameterTypes[2].equals(SQLException.class)) {
if (constructorType < MESSAGE_SQL_SQLEX_CONSTRUCTOR)
constructorType = MESSAGE_SQL_SQLEX_CONSTRUCTOR;
}
}
// invoke constructor
Constructor exceptionConstructor = null;
switch (constructorType) {
case MESSAGE_SQL_SQLEX_CONSTRUCTOR:
Class[] messageAndSqlAndSqlExArgsClass = new Class[] {String.class, String.class, SQLException.class};
Object[] messageAndSqlAndSqlExArgs = new Object[] {task, sql, sqlEx};
exceptionConstructor = exceptionClass.getConstructor(messageAndSqlAndSqlExArgsClass);
return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlAndSqlExArgs);
case MESSAGE_SQL_THROWABLE_CONSTRUCTOR:
Class[] messageAndSqlAndThrowableArgsClass = new Class[] {String.class, String.class, Throwable.class};
Object[] messageAndSqlAndThrowableArgs = new Object[] {task, sql, sqlEx};
exceptionConstructor = exceptionClass.getConstructor(messageAndSqlAndThrowableArgsClass);
return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlAndThrowableArgs);
case MESSAGE_SQLEX_CONSTRUCTOR:
Class[] messageAndSqlExArgsClass = new Class[] {String.class, SQLException.class};
Object[] messageAndSqlExArgs = new Object[] {task + ": " + sqlEx.getMessage(), sqlEx};
exceptionConstructor = exceptionClass.getConstructor(messageAndSqlExArgsClass);
return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlExArgs);
case MESSAGE_THROWABLE_CONSTRUCTOR:
Class[] messageAndThrowableArgsClass = new Class[] {String.class, Throwable.class};
Object[] messageAndThrowableArgs = new Object[] {task + ": " + sqlEx.getMessage(), sqlEx};
exceptionConstructor = exceptionClass.getConstructor(messageAndThrowableArgsClass);
return (DataAccessException)exceptionConstructor.newInstance(messageAndThrowableArgs);
case MESSAGE_ONLY_CONSTRUCTOR:
Class[] messageOnlyArgsClass = new Class[] {String.class};
Object[] messageOnlyArgs = new Object[] {task + ": " + sqlEx.getMessage()};
exceptionConstructor = exceptionClass.getConstructor(messageOnlyArgsClass);
return (DataAccessException) exceptionConstructor.newInstance(messageOnlyArgs);
default:
logger.warn("Unable to find appropriate constructor of custom exception class [" +
exceptionClass.getName() + "]");
return null;
}
}
catch (Exception ex) {
if (logger.isWarnEnabled()) {
logger.warn("Unable to instantiate custom exception class [" + exceptionClass.getName() + "]", ex);
}
return null;
}
}
private void logTranslation(String task, String sql, SQLException sqlEx, boolean custom) {
if (logger.isDebugEnabled()) {
String intro = custom ? "Custom translation of" : "Translating";
logger.debug(intro + " SQLException with SQLState '" + sqlEx.getSQLState() +
"' and errorCode '" + sqlEx.getErrorCode() + "' and message [" + sqlEx.getMessage() +
"]; SQL was [" + sql + "] for task [" + task + "]");
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -