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:
-
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. -
Cualquier implementación personalizada de la interfaz
SQLExceptionTranslator
, que se expone como una propiedadcustomSqlExceptionTranslator
de la claseSQLErrorCodes
. -
Se busca una coincidencia en la lista de instancias de la clase
CustomSQLErrorCodesTranslation
(proporcionada para la propiedadcustomTranslations
de la claseSQLErrorCodes
). -
Se aplica la asignación de código de error.
-
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 esSQLStateSQLExceptionTranslator
.
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:
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;
}
}
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:
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);
}
// 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
.
GO TO FULL VERSION