Search in sources :

Example 1 with TransientDataAccessResourceException

use of org.springframework.dao.TransientDataAccessResourceException in project spring-framework by spring-projects.

the class SQLErrorCodeSQLExceptionTranslator method doTranslate.

@Override
protected DataAccessException doTranslate(String task, String sql, SQLException ex) {
    SQLException sqlEx = ex;
    if (sqlEx instanceof BatchUpdateException && sqlEx.getNextException() != null) {
        SQLException nestedSqlEx = sqlEx.getNextException();
        if (nestedSqlEx.getErrorCode() > 0 || nestedSqlEx.getSQLState() != null) {
            logger.debug("Using nested SQLException from the BatchUpdateException");
            sqlEx = nestedSqlEx;
        }
    }
    // First, try custom translation from overridden method.
    DataAccessException dex = customTranslate(task, sql, sqlEx);
    if (dex != null) {
        return dex;
    }
    // Next, try the custom SQLException translator, if available.
    if (this.sqlErrorCodes != null) {
        SQLExceptionTranslator customTranslator = this.sqlErrorCodes.getCustomSqlExceptionTranslator();
        if (customTranslator != null) {
            DataAccessException customDex = customTranslator.translate(task, sql, sqlEx);
            if (customDex != null) {
                return customDex;
            }
        }
    }
    // Check SQLErrorCodes with corresponding error code, if available.
    if (this.sqlErrorCodes != null) {
        String errorCode;
        if (this.sqlErrorCodes.isUseSqlStateForTranslation()) {
            errorCode = sqlEx.getSQLState();
        } else {
            // 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 (CustomSQLErrorCodesTranslation customTranslation : customTranslations) {
                    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.getDuplicateKeyCodes(), errorCode) >= 0) {
                logTranslation(task, sql, sqlEx, false);
                return new DuplicateKeyException(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.getPermissionDeniedCodes(), errorCode) >= 0) {
                logTranslation(task, sql, sqlEx, false);
                return new PermissionDeniedDataAccessException(buildMessage(task, sql, sqlEx), 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.getTransientDataAccessResourceCodes(), errorCode) >= 0) {
                logTranslation(task, sql, sqlEx, false);
                return new TransientDataAccessResourceException(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()) {
        String codes;
        if (this.sqlErrorCodes != null && this.sqlErrorCodes.isUseSqlStateForTranslation()) {
            codes = "SQL state '" + sqlEx.getSQLState() + "', error code '" + sqlEx.getErrorCode();
        } else {
            codes = "Error code '" + sqlEx.getErrorCode() + "'";
        }
        logger.debug("Unable to translate SQLException with " + codes + ", will now try the fallback translator");
    }
    return null;
}
Also used : BadSqlGrammarException(org.springframework.jdbc.BadSqlGrammarException) TransientDataAccessResourceException(org.springframework.dao.TransientDataAccessResourceException) CannotAcquireLockException(org.springframework.dao.CannotAcquireLockException) SQLException(java.sql.SQLException) DataAccessResourceFailureException(org.springframework.dao.DataAccessResourceFailureException) PermissionDeniedDataAccessException(org.springframework.dao.PermissionDeniedDataAccessException) InvalidResultSetAccessException(org.springframework.jdbc.InvalidResultSetAccessException) DuplicateKeyException(org.springframework.dao.DuplicateKeyException) DataIntegrityViolationException(org.springframework.dao.DataIntegrityViolationException) CannotSerializeTransactionException(org.springframework.dao.CannotSerializeTransactionException) DeadlockLoserDataAccessException(org.springframework.dao.DeadlockLoserDataAccessException) DataAccessException(org.springframework.dao.DataAccessException) DeadlockLoserDataAccessException(org.springframework.dao.DeadlockLoserDataAccessException) PermissionDeniedDataAccessException(org.springframework.dao.PermissionDeniedDataAccessException) BatchUpdateException(java.sql.BatchUpdateException)

Example 2 with TransientDataAccessResourceException

use of org.springframework.dao.TransientDataAccessResourceException in project spring-framework by spring-projects.

the class CustomSQLExceptionTranslatorRegistrarTests method customErrorCodeTranslation.

@Test
@SuppressWarnings("resource")
public void customErrorCodeTranslation() {
    new ClassPathXmlApplicationContext("test-custom-translators-context.xml", CustomSQLExceptionTranslatorRegistrarTests.class);
    SQLErrorCodes codes = SQLErrorCodesFactory.getInstance().getErrorCodes("H2");
    SQLErrorCodeSQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator();
    sext.setSqlErrorCodes(codes);
    DataAccessException exFor4200 = sext.doTranslate("", "", new SQLException("Ouch", "42000", 42000));
    assertNotNull("Should have been translated", exFor4200);
    assertTrue("Should have been instance of BadSqlGrammarException", BadSqlGrammarException.class.isAssignableFrom(exFor4200.getClass()));
    DataAccessException exFor2 = sext.doTranslate("", "", new SQLException("Ouch", "42000", 2));
    assertNotNull("Should have been translated", exFor2);
    assertTrue("Should have been instance of TransientDataAccessResourceException", TransientDataAccessResourceException.class.isAssignableFrom(exFor2.getClass()));
    DataAccessException exFor3 = sext.doTranslate("", "", new SQLException("Ouch", "42000", 3));
    assertNull("Should not have been translated", exFor3);
}
Also used : BadSqlGrammarException(org.springframework.jdbc.BadSqlGrammarException) TransientDataAccessResourceException(org.springframework.dao.TransientDataAccessResourceException) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) SQLException(java.sql.SQLException) DataAccessException(org.springframework.dao.DataAccessException) Test(org.junit.Test)

Example 3 with TransientDataAccessResourceException

use of org.springframework.dao.TransientDataAccessResourceException in project spring-framework by spring-projects.

the class SQLExceptionSubclassTranslatorTests method errorCodeTranslation.

@Test
public void errorCodeTranslation() {
    SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES);
    SQLException dataIntegrityViolationEx = SQLExceptionSubclassFactory.newSQLDataException("", "", 0);
    DataIntegrityViolationException divex = (DataIntegrityViolationException) sext.translate("task", "SQL", dataIntegrityViolationEx);
    assertEquals(dataIntegrityViolationEx, divex.getCause());
    SQLException featureNotSupEx = SQLExceptionSubclassFactory.newSQLFeatureNotSupportedException("", "", 0);
    InvalidDataAccessApiUsageException idaex = (InvalidDataAccessApiUsageException) sext.translate("task", "SQL", featureNotSupEx);
    assertEquals(featureNotSupEx, idaex.getCause());
    SQLException dataIntegrityViolationEx2 = SQLExceptionSubclassFactory.newSQLIntegrityConstraintViolationException("", "", 0);
    DataIntegrityViolationException divex2 = (DataIntegrityViolationException) sext.translate("task", "SQL", dataIntegrityViolationEx2);
    assertEquals(dataIntegrityViolationEx2, divex2.getCause());
    SQLException permissionDeniedEx = SQLExceptionSubclassFactory.newSQLInvalidAuthorizationSpecException("", "", 0);
    PermissionDeniedDataAccessException pdaex = (PermissionDeniedDataAccessException) sext.translate("task", "SQL", permissionDeniedEx);
    assertEquals(permissionDeniedEx, pdaex.getCause());
    SQLException dataAccessResourceEx = SQLExceptionSubclassFactory.newSQLNonTransientConnectionException("", "", 0);
    DataAccessResourceFailureException darex = (DataAccessResourceFailureException) sext.translate("task", "SQL", dataAccessResourceEx);
    assertEquals(dataAccessResourceEx, darex.getCause());
    SQLException badSqlEx2 = SQLExceptionSubclassFactory.newSQLSyntaxErrorException("", "", 0);
    BadSqlGrammarException bsgex2 = (BadSqlGrammarException) sext.translate("task", "SQL2", badSqlEx2);
    assertEquals("SQL2", bsgex2.getSql());
    assertEquals(badSqlEx2, bsgex2.getSQLException());
    SQLException tranRollbackEx = SQLExceptionSubclassFactory.newSQLTransactionRollbackException("", "", 0);
    ConcurrencyFailureException cfex = (ConcurrencyFailureException) sext.translate("task", "SQL", tranRollbackEx);
    assertEquals(tranRollbackEx, cfex.getCause());
    SQLException transientConnEx = SQLExceptionSubclassFactory.newSQLTransientConnectionException("", "", 0);
    TransientDataAccessResourceException tdarex = (TransientDataAccessResourceException) sext.translate("task", "SQL", transientConnEx);
    assertEquals(transientConnEx, tdarex.getCause());
    SQLException transientConnEx2 = SQLExceptionSubclassFactory.newSQLTimeoutException("", "", 0);
    QueryTimeoutException tdarex2 = (QueryTimeoutException) sext.translate("task", "SQL", transientConnEx2);
    assertEquals(transientConnEx2, tdarex2.getCause());
    SQLException recoverableEx = SQLExceptionSubclassFactory.newSQLRecoverableException("", "", 0);
    RecoverableDataAccessException rdaex2 = (RecoverableDataAccessException) sext.translate("task", "SQL", recoverableEx);
    assertEquals(recoverableEx, rdaex2.getCause());
    // Test classic error code translation. We should move there next if the exception we pass in is not one
    // of the new sub-classes.
    SQLException sexEct = new SQLException("", "", 1);
    BadSqlGrammarException bsgEct = (BadSqlGrammarException) sext.translate("task", "SQL-ECT", sexEct);
    assertEquals("SQL-ECT", bsgEct.getSql());
    assertEquals(sexEct, bsgEct.getSQLException());
    // Test fallback. We assume that no database will ever return this error code,
    // but 07xxx will be bad grammar picked up by the fallback SQLState translator
    SQLException sexFbt = new SQLException("", "07xxx", 666666666);
    BadSqlGrammarException bsgFbt = (BadSqlGrammarException) sext.translate("task", "SQL-FBT", sexFbt);
    assertEquals("SQL-FBT", bsgFbt.getSql());
    assertEquals(sexFbt, bsgFbt.getSQLException());
    // and 08xxx will be data resource failure (non-transient) picked up by the fallback SQLState translator
    SQLException sexFbt2 = new SQLException("", "08xxx", 666666666);
    DataAccessResourceFailureException darfFbt = (DataAccessResourceFailureException) sext.translate("task", "SQL-FBT2", sexFbt2);
    assertEquals(sexFbt2, darfFbt.getCause());
}
Also used : BadSqlGrammarException(org.springframework.jdbc.BadSqlGrammarException) QueryTimeoutException(org.springframework.dao.QueryTimeoutException) TransientDataAccessResourceException(org.springframework.dao.TransientDataAccessResourceException) SQLException(java.sql.SQLException) DataAccessResourceFailureException(org.springframework.dao.DataAccessResourceFailureException) InvalidDataAccessApiUsageException(org.springframework.dao.InvalidDataAccessApiUsageException) ConcurrencyFailureException(org.springframework.dao.ConcurrencyFailureException) PermissionDeniedDataAccessException(org.springframework.dao.PermissionDeniedDataAccessException) RecoverableDataAccessException(org.springframework.dao.RecoverableDataAccessException) DataIntegrityViolationException(org.springframework.dao.DataIntegrityViolationException) Test(org.junit.Test)

Aggregations

SQLException (java.sql.SQLException)3 TransientDataAccessResourceException (org.springframework.dao.TransientDataAccessResourceException)3 BadSqlGrammarException (org.springframework.jdbc.BadSqlGrammarException)3 Test (org.junit.Test)2 DataAccessException (org.springframework.dao.DataAccessException)2 DataAccessResourceFailureException (org.springframework.dao.DataAccessResourceFailureException)2 DataIntegrityViolationException (org.springframework.dao.DataIntegrityViolationException)2 PermissionDeniedDataAccessException (org.springframework.dao.PermissionDeniedDataAccessException)2 BatchUpdateException (java.sql.BatchUpdateException)1 ClassPathXmlApplicationContext (org.springframework.context.support.ClassPathXmlApplicationContext)1 CannotAcquireLockException (org.springframework.dao.CannotAcquireLockException)1 CannotSerializeTransactionException (org.springframework.dao.CannotSerializeTransactionException)1 ConcurrencyFailureException (org.springframework.dao.ConcurrencyFailureException)1 DeadlockLoserDataAccessException (org.springframework.dao.DeadlockLoserDataAccessException)1 DuplicateKeyException (org.springframework.dao.DuplicateKeyException)1 InvalidDataAccessApiUsageException (org.springframework.dao.InvalidDataAccessApiUsageException)1 QueryTimeoutException (org.springframework.dao.QueryTimeoutException)1 RecoverableDataAccessException (org.springframework.dao.RecoverableDataAccessException)1 InvalidResultSetAccessException (org.springframework.jdbc.InvalidResultSetAccessException)1