【发布时间】:2020-08-19 16:17:56
【问题描述】:
我需要阻止表中某些列的更新操作并显示消息。我正在使用 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: could not execute statement。
- 如何获取触发器中描述的消息(即PSQLException:不允许更新 created_by 的值)
- 如果我删除
JpaSystemException,handleTriggerException 不再起作用,为什么?
环境:
框架:Spring Boot
ORM:休眠
数据库: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
【问题讨论】:
-
Caused by:表示需要调用getCause()来获取底层异常。 -
感谢@Andreas,我尝试过
getCause()和其他方法,但不幸的是,它们都给出了相同的消息org.hibernate.exception.GenericJDBCException: could not execute statement。 我已经相应地更新了问题 -
如果您转换为 JdbcException 或 GenericJDBCException,您可以提取根 sqlexception、错误代码或 sql 状态等信息
-
谢谢@CodeScale,我已经使用
ExceptionUtils解决了这个问题 -
谢谢,@Andreas。为您的提示。我可以使用
ExceptionUtils和getRootCause(throwable)获取消息
标签: java spring hibernate spring-boot spring-data-jpa