Обработка ошибок в Spring JDBC

DSC_0588Как использует исключение SQLException для публикации ошибок, так и использует исключение DataAccessException с той же целью. Иерархия классов, начинающаяся с DataAccessExeption не привязана к и применяется в достаточно широком смысле внутри Spring для работы с данными. Преобразование из низкоуровневых классов исключений, характерных для конкретной реализации механизма работы с данными ( SQLExeption в нашем случае) производится с помощью механизма переводчиков исключений и, в контексте Spring , конкретно с помощью реализаций интерфейса SQLExceptionTranslator.

По умолчанию используется реализация SQLErrorCodeSQLExceptionTranslator, которая переводит исключения используя свои знания о конкретных базах данных и их кодах ошибок. Вместе со Spring JDBC распространяется файл sql-error-codes.xml c описаниями кодов ошибок, характерных для конкретных баз данных. Spring JDBC автоматически определяет базу, с которой он работает и использует списки ошибок от этой базы.

Если есть необходимость, можно расширить SQLErrorCodeSQLExceptionTranslator, добавить собственные ошибки или вмешаться в процесс обработки.

Допустим у нас в базе есть процедура, возвращающая наш собственный нестандартный SQLState:

И я бы хотел кидать особенное исключение, когда эта функция вызывается:

Для этого я расширяю SQLErrorCodeSQLExceptionTranslator и переопределяю в нём метод customTranslate(), который должен либо вернуть какое-нибудь исключение, унаследованное от DataAccessException, либо null. В первом случае обработка сразу прекратиться, во втором управление будет передано механизму по умолчанию.

Собственный транслятор исключений назначается всему экземпляру JdbcTemplate с помощью метода setExceptionTranslator(). У экземпляра JdbcTemplate может быть только один транслятор, поэтому если вы решите не расширять SQLErrorCodeSQLExceptionTranslator, а реализовывать SQLExceptionTranslator самостоятельно, вам придётся анализировать все исключения SQL и самостоятельно их всех транслировать.

Подключение к внешним базам данных.

Код из примера выше использует не встроенную базу данных, а внешнюю базу. Поэтому XML описание контекста несколько другое. В частности для :

Для других баз данных идеологически описание DataSource остаётся тем же самым, но детали могут отличаться.

Код примера доступен на github. Код из примера использует PostgreSQL. В applicationContext.xml примера следует заменить адрес сервера с ‘127.0.0.1’ на адрес вашего PostgreSQL сервера, если он установлен не на локальной машине. Перед запуском необходимо так же исполнить скрипт schema.sql