org.jfaster.mango.jdbc.SQLStateSQLExceptionTranslator Maven / Gradle / Ivy
/*
* Copyright 2014 mango.jfaster.org
*
* The Mango Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.jfaster.mango.jdbc;
import org.jfaster.mango.jdbc.exception.*;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;
/**
* @author ash
*/
public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLExceptionTranslator {
private static final Set BAD_SQL_GRAMMAR_CODES = new HashSet(8);
private static final Set DATA_INTEGRITY_VIOLATION_CODES = new HashSet(8);
private static final Set DATA_ACCESS_RESOURCE_FAILURE_CODES = new HashSet(8);
private static final Set TRANSIENT_DATA_ACCESS_RESOURCE_CODES = new HashSet(8);
private static final Set CONCURRENCY_FAILURE_CODES = new HashSet(4);
static {
BAD_SQL_GRAMMAR_CODES.add("07"); // Dynamic SQL error
BAD_SQL_GRAMMAR_CODES.add("21"); // Cardinality violation
BAD_SQL_GRAMMAR_CODES.add("2A"); // Syntax error direct SQL
BAD_SQL_GRAMMAR_CODES.add("37"); // Syntax error dynamic SQL
BAD_SQL_GRAMMAR_CODES.add("42"); // General SQL syntax error
BAD_SQL_GRAMMAR_CODES.add("65"); // Oracle: unknown identifier
DATA_INTEGRITY_VIOLATION_CODES.add("01"); // Data truncation
DATA_INTEGRITY_VIOLATION_CODES.add("02"); // No data found
DATA_INTEGRITY_VIOLATION_CODES.add("22"); // Value out of range
DATA_INTEGRITY_VIOLATION_CODES.add("23"); // Integrity constraint violation
DATA_INTEGRITY_VIOLATION_CODES.add("27"); // Triggered data change violation
DATA_INTEGRITY_VIOLATION_CODES.add("44"); // With check violation
DATA_ACCESS_RESOURCE_FAILURE_CODES.add("08"); // Connection exception
DATA_ACCESS_RESOURCE_FAILURE_CODES.add("53"); // PostgreSQL: insufficient resources (e.g. disk full)
DATA_ACCESS_RESOURCE_FAILURE_CODES.add("54"); // PostgreSQL: program limit exceeded (e.g. statement too complex)
DATA_ACCESS_RESOURCE_FAILURE_CODES.add("57"); // DB2: out-of-memory exception / database not started
DATA_ACCESS_RESOURCE_FAILURE_CODES.add("58"); // DB2: unexpected system error
TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("JW"); // Sybase: internal I/O error
TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("JZ"); // Sybase: unexpected I/O error
TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("S1"); // DB2: communication failure
CONCURRENCY_FAILURE_CODES.add("40"); // Transaction rollback
CONCURRENCY_FAILURE_CODES.add("61"); // Oracle: deadlock
}
@Override
protected DataAccessException doTranslate(String sql, SQLException ex) {
String sqlState = getSqlState(ex);
if (sqlState != null && sqlState.length() >= 2) {
String classCode = sqlState.substring(0, 2);
if (logger.isDebugEnabled()) {
logger.debug("Extracted SQL state class '" + classCode + "' from value '" + sqlState + "'");
}
if (BAD_SQL_GRAMMAR_CODES.contains(classCode)) {
return new BadSqlGrammarException(sql, ex);
} else if (DATA_INTEGRITY_VIOLATION_CODES.contains(classCode)) {
return new DataIntegrityViolationException(buildMessage(sql, ex), ex);
} else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) {
return new DataAccessResourceFailureException(buildMessage(sql, ex), ex);
} else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) {
return new TransientDataAccessResourceException(buildMessage(sql, ex), ex);
} else if (CONCURRENCY_FAILURE_CODES.contains(classCode)) {
return new ConcurrencyFailureException(buildMessage(sql, ex), ex);
}
}
return null;
}
/**
* Gets the SQL state code from the supplied {@link SQLException exception}.
* Some JDBC drivers nest the actual exception from a batched update, so we
* might need to dig down into the nested exception.
*
* @param ex the exception from which the {@link SQLException#getSQLState() SQL state}
* is to be extracted
* @return the SQL state code
*/
private String getSqlState(SQLException ex) {
String sqlState = ex.getSQLState();
if (sqlState == null) {
SQLException nestedEx = ex.getNextException();
if (nestedEx != null) {
sqlState = nestedEx.getSQLState();
}
}
return sqlState;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy