У меня есть требование предотвратить действие обновления для столбцов 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