Java Spring引导:处理从数据库触发器引发的异常
我需要阻止表中ceratin列的更新操作并显示消息。我正在使用liquibase来管理数据库模式。为了实现这一点,我使用了触发器函数和触发器,它们工作得很好 功能Java Spring引导:处理从数据库触发器引发的异常,java,spring,hibernate,spring-boot,spring-data-jpa,Java,Spring,Hibernate,Spring Boot,Spring Data Jpa,我需要阻止表中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
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;$$;
@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);
}
我正在使用
@ControllerAdvice
和@ExceptionHandler
以及PSQLException.class、genericjdbception.class、JpaSystemException.class来管理异常处理,我能够处理异常。为了验证功能,当我点击API来更新受限列的值时,触发器引发了异常,我可以在控制台中看到以下内容
handleTriggerException
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;$$;
@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);
}
问题是
当前,ex.getMessage()
返回org.hibernate.exception.genericjdbception:无法执行语句
- 如何获取触发器中描述的消息(即PSQLException:不允许更新)
创造的价值(由)
- 如果我删除
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
@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);
}
与一起使用将显示根本原因消息
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
@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);
}
@ExceptionHandler({psqleexception.class,genericjdbception.class,JpaSystemException.class})
公共响应handleTriggerException(异常示例,NativeWebRequest请求){
Problem=Problem.builder()
.withStatus(状态错误请求)
.withDetail(ExceptionUtils.getRootCause(ex).getMessage())
.build();
返回创建(例如,问题,请求);
}
原因:
意味着您需要调用getCause()
来获取底层异常。感谢@Andreas,我尝试了getCause()
和其他方法,但不幸的是,它们都给出了相同的消息org.hibernate.exception.genericjdbception:无法执行语句。我已经相应地更新了问题。如果您转换为JdbcException或GenericJDBCException,那么您可以提取根sqlexception、错误代码或sql状态等信息。谢谢,@CodeScale,我已经使用ExceptionUtils
谢谢,@Andreas解决了这个问题。谢谢你的提示。我可以使用ExceptionUtils
和getRootCause(throwable)
获取消息如果您指定了ExceptionUtils
是什么,这个答案可能会更有用。