SQLExceptionTranslator es una interfaz que debe ser implementada por clases capaces de convertir entre SQLExceptions y org.springframework.dao.DataAccessException nativo, que No dependa de la estrategia de acceso a los datos. Las implementaciones se pueden escribir (por ejemplo, usando códigos SQLState para JDBC) o propietarias (por ejemplo, usando códigos de error de Oracle) para una mayor precisión.

SQLErrorCodeSQLExceptionTranslator es la implementación predeterminada de SQLExceptionTranslator. Esta implementación utiliza códigos de proveedores específicos. Es más precisa que la implementación SQLState. La conversión del código de error se basa en códigos almacenados en una clase de tipo JavaBean llamada SQLErrorCodes. Esta clase es creada y completada por SQLErrorCodesFactory, que (como su nombre indica) es una fábrica para crear SQLErrorCodes en función del contenido del archivo de configuración sql-error-codes.xml. Este archivo se completa con códigos de fabricante y se basa en el DatabaseProductName tomado del DatabaseMetaData. Los códigos utilizados son para la base de datos real que estás utilizando.

SQLErrorCodeSQLExceptionTranslator aplica reglas de negociación en la siguiente secuencia:

  1. Cualquier transformación personalizada implementada por una subclase. Normalmente se utiliza un SQLErrorCodeSQLExceptionTranslator específico, por lo que esta regla no se aplica. Solo se aplica si realmente proporcionaste una implementación de la subclase.

  2. Cualquier implementación personalizada de la interfaz SQLExceptionTranslator, que se expone como una propiedad customSqlExceptionTranslator de la clase SQLErrorCodes.

  3. Se busca una coincidencia en la lista de instancias de la clase CustomSQLErrorCodesTranslation (proporcionada para la propiedad customTranslations de la clase SQLErrorCodes).

  4. Se aplica la asignación de código de error.

  5. Se utiliza un convertidor de retorno (traductor). SQLExceptionSubclassTranslator es el traductor predeterminado. Si esta traducción no está disponible, la siguiente transformación a devolver es SQLStateSQLExceptionTranslator.

SQLErrorCodesFactory se utiliza de forma predeterminada para definir códigos Error y transformaciones de excepciones personalizadas. Se buscan en el archivo sql-error-codes.xml de la ruta de clases, y la instancia correspondiente de SQLErrorCodes se encuentra en función del nombre de la base de datos de los metadatos del base de datos que se está utilizando.

Puede ampliar SQLErrorCodeSQLExceptionTranslator, como se muestra en el siguiente ejemplo:

Java
public class CustomSQLErrorCodesTranslator extends SQLErrorCodeSQLExceptionTranslator {
    protected DataAccessException customTranslate(String task, String sql, SQLException sqlEx) {
        if (sqlEx.getErrorCode() == -12345) {
            return new DeadlockLoserDataAccessException(task, sqlEx);
        }
        return null;
    }
}
Kotlin
class CustomSQLErrorCodesTranslator : SQLErrorCodeSQLExceptionTranslator() {
    override fun customTranslate(task: String, sql: String?, sqlEx: SQLException): DataAccessException? {
        if (sqlEx.errorCode == -12345) {
            return DeadlockLoserDataAccessException(task, sqlEx)
        }
        return null
    }
}

El ejemplo anterior convierte un código de error específico (-12345) y deja otros errores a la implementación del convertidor estándar. Para usar este traductor personalizado, debe pasarlo a JdbcTemplate mediante el método setExceptionTranslator y luego usar este JdbcTemplate para cualquier manejo de acceso a datos donde se requiere un convertidor. El siguiente ejemplo muestra cómo se puede utilizar este convertidor personalizado:

Java

private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
    // crea un JdbcTemplate y establece la fuente de datos
    this.jdbcTemplate = new JdbcTemplate();
    this.jdbcTemplate.setDataSource(dataSource);
    // crea un transformador personalizado y configura la fuente de datos para buscar la transformación predeterminada
    CustomSQLErrorCodesTranslator tr = new CustomSQLErrorCodesTranslator();
    tr.setDataSource(dataSource);
    this.jdbcTemplate.setExceptionTranslator(tr);
}
public void updateShippingCharge(long orderId, long pct) {
    // usa el JdbcTemplate preparado para esta actualización
    this.jdbcTemplate.update("update orders" +
        " set shipping_charge = shipping_charge * ? / 100" +
        " where id = ?", pct, orderId);
}
Kotlin

// crea una plantilla JdbcTemplate y establece la fuente de datos
private val jdbcTemplate = JdbcTemplate(dataSource).apply {
    // crea un transformador personalizado y configura la fuente de datos para buscar la transformación predeterminada
    exceptionTranslator = CustomSQLErrorCodesTranslator().apply {
        this.dataSource = dataSource
    }
}
fun updateShippingCharge(orderId: Long, pct: Long) {
    // usa el JdbcTemplate preparado para esta actualización
    this.jdbcTemplate!!.update("update orders" +
            " set shipping_charge = shipping_charge * ? / 100" +
            " where id = ?", pct, orderId)
}

Al solucionador personalizado se le pasa una fuente de datos para buscar códigos de error en sql-error-codes.xml.