Spring Boot: обработка возбужденного исключения из триггера базы данных - PullRequest
0 голосов
/ 05 мая 2020

У меня есть требование предотвратить действие обновления для столбцов ceratin в таблице и отобразить сообщение. Я использую Liquibase для управления схемой базы данных. Для этого я использовал триггерные функции и триггеры, которые отлично работают.

Функция

CREATE OR REPLACE FUNCTION FN_BU_CATEGORY() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN
   IF NEW.created_by <> OLD.created_by THEN
      RAISE EXCEPTION 'Not allowed to update the value of created_by';
   END IF;
   RETURN NEW;
END;$$;

Триггер:

CREATE TRIGGER TR_BU_CATEGORY
BEFORE UPDATE ON category FOR EACH ROW
EXECUTE PROCEDURE FN_BU_CATEGORY();

Я управляю обработкой исключений, используя @ControllerAdvice и @ExceptionHandler с PSQLException.class, GenericJDBCException.class, JpaSystemException.class, и я смог обработать исключение. Чтобы проверить функциональность, когда я делаю обращение к API, чтобы обновить значения ограниченных столбцов, триггер вызвал исключение, и я вижу в консоли следующее.

handleTriggerException

@ExceptionHandler({PSQLException.class, GenericJDBCException.class, JpaSystemException.class})
public ResponseEntity<Problem> handleTriggerException(Exception ex, NativeWebRequest request) {
    Problem problem = Problem.builder()
        .withStatus(Status.BAD_REQUEST)
        .withDetail("Test Message " + ex.getMessage())
        .build();
    return create(ex, problem, request);
}

Консоль:

Hibernate: update category set created_by = 'abc' where id = 1234
19:37:49.126 [XNIO-1 task-9] WARN  o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: P0001
19:37:49.127 [XNIO-1 task-9] ERROR o.h.e.jdbc.spi.SqlExceptionHelper - ERROR: Not allowed to update 
the value of created_by
  Where: PL/pgSQL function noupdate() line 3 at RAISE
.......
org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is 
org.hibernate.exception.GenericJDBCException: could not execute statement
Caused by: org.postgresql.util.PSQLException: ERROR: Not allowed to update the value of created_by
Where: PL/pgSQL function noupdate() line 3 at RAISE

Вопрос

В настоящее время ex.getMessage() возвращает org.hibernate.exception.GenericJDBCException: не удалось выполнить оператор .

  • Как я могу получить сообщение, описанное в триггере (т.е. PSQLException : Не разрешено обновлять значение created_by )
  • Если я удалю JpaSystemException, handleTriggerException больше не работает, почему?

Среда:

Фреймворк: Spring Boot
ORM: Hibernate
База данных: Postgres 11


ОБНОВЛЕНИЕ:

Я пытался получить сообщение следующими способами, но, к сожалению, все они возвращают одно и то же сообщение.

System.out.println("1: " +ex.getCause());
System.out.println("2: " +ex.getMessage());
System.out.println("3: " +ex.getLocalizedMessage());
System.out.println("4: " +ex.fillInStackTrace());
System.out.println("5: " +ex.getStackTrace());

1: org.hibernate.exception.GenericJDBCException: could not execute statement
2: could not execute statement; nested exception is         org.hibernate.exception.GenericJDBCException: could not execute statement
3: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
4: org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement    
5: [Ljava.lang.StackTraceElement;@6f3072be

1 Ответ

0 голосов
/ 05 мая 2020

Использование ExceptionUtils с getRootCause (throwable) дает сообщение о причине root.

@ExceptionHandler({PSQLException.class, GenericJDBCException.class, JpaSystemException.class})
public ResponseEntity<Problem> handleTriggerException(Exception ex, NativeWebRequest request) {

        Problem problem = Problem.builder()
            .withStatus(Status.BAD_REQUEST)
            .withDetail(ExceptionUtils.getRootCause(ex).getMessage())
            .build();
        return create(ex, problem, request);
}

Как получить root сообщение о причине?

...