spring-data-jdbc — Почему я получаю исключение DbActionExecutionException вместо исключения DuplicateKeyException

#spring-boot #spring-data-jdbc

#spring-boot #spring-data-jdbc

Вопрос:

Используя :

  • весенняя загрузка 2.3.6.RELEASE
  • spring-data-jdbc.
  • postgresql

Я создал простой репозиторий, расширив CrudRepository, и он отлично работает. Например, я могу сохранять данные, используя этот репозиторий.

Я создал уникальный индекс в одном из столбцов и ожидал, что мой репозиторий выдаст исключение org.springframework.dao.DuplicateKeyException при попытке вставить один и тот же объект дважды.

Однако вместо этого репозиторий выдает org.springframework.data.relational.core.conversion.Исключение DbActionExecutionException, которое имеет исключение DuplicateKeyException, имеет свою причину.

Моя конфигурация довольно проста: только настройка источника данных (spring.datasource. *)

Является ли это нормальным поведением spring-data-jdbc для переноса исключения DuplicateKeyException в исключение DbActionExecutionException ?
Я использовал spring-data в прошлом и не могу вспомнить, что имел дело с DbActionExecutionException.

Ответ №1:

В Spring-Data-Jdbc это ожидаемое поведение. Spring-Data-Jdbc использует JdbcTemplate при выполнении любого DBAction с использованием CrudRepository.

Все действия DB, выполняемые CrudRepository, будут переведены в исключение DbActionExecutionException, если какое-либо исключение выдается JdbcTemplate.

Фрагмент из класса AggregateChangeExecutor:

 private void execute(DbAction<?> action, JdbcAggregateChangeExecutionContext executionContext) {

        try {
            if (action instanceof DbAction.InsertRoot) {
                executionContext.executeInsertRoot((DbAction.InsertRoot<?>) action);
            } else if (action instanceof DbAction.Insert) {
                executionContext.executeInsert((DbAction.Insert<?>) action);
            } else if (action instanceof DbAction.UpdateRoot) {
                executionContext.executeUpdateRoot((DbAction.UpdateRoot<?>) action);
            } else if (action instanceof DbAction.Update) {
                executionContext.executeUpdate((DbAction.Update<?>) action);
            } else if (action instanceof DbAction.Delete) {
                executionContext.executeDelete((DbAction.Delete<?>) action);
            } else if (action instanceof DbAction.DeleteAll) {
                executionContext.executeDeleteAll((DbAction.DeleteAll<?>) action);
            } else if (action instanceof DbAction.DeleteRoot) {
                executionContext.executeDeleteRoot((DbAction.DeleteRoot<?>) action);
            } else if (action instanceof DbAction.DeleteAllRoot) {
                executionContext.executeDeleteAllRoot((DbAction.DeleteAllRoot<?>) action);
            } else if (action instanceof DbAction.AcquireLockRoot) {
                executionContext.executeAcquireLock((DbAction.AcquireLockRoot<?>) action);
            } else if (action instanceof DbAction.AcquireLockAllRoot) {
                executionContext.executeAcquireLockAllRoot((DbAction.AcquireLockAllRoot<?>) action);
            } else {
                throw new RuntimeException("unexpected action");
            }
        } catch (Exception e) {
            throw new DbActionExecutionException(action, e);
        }
    }
  

JdbcTemplate выдает исключение DataAccessException во время выполнения DBAction, и все классы исключений, связанные с транзакцией Spring, реализуют исключение DataAccessException.

Ответ №2:

Это класс-оболочка для действий с базой данных.

проверьте эту ссылку (https://docs.spring.io/spring-data/jdbc/docs/1.0.0.M2/api/org/springframework/data/jdbc/core/conversion/DbActionExecutionException.html).

Комментарии:

1. Действительно, я видел этот класс, прежде чем задавать вопрос. Мне было интересно, относится ли это перенос к spring-data-jdbc, потому что я уверен, что в аналогичном контексте (используя spring-data) я мог бы напрямую перехватить все исключения DataAccessException.