无法获取PSQLException的错误消息

时间:2018-04-12 15:44:14

标签: java postgresql spring-boot exception-handling spring-data-jpa

我开发了一个API服务,它将一些数据添加到数据库中。我对我的实体的name字段设置了唯一约束。每当我尝试插入重复的name值时,我都会给出以下堆栈跟踪。

Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "uk_tten_courseservice_program_table_program_name"
  Detail: Key (program_name)=(jkjkncj) already exists.
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
    ... 119 more

这是嵌套异常之一,我希望将错误消息发送到前端。根本例外是:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [uk_tten_courseservice_program_table_program_name]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

我在实体课程中添加的内容如下:

@Entity
@Table(name = "tten_courseservice_program_table", uniqueConstraints = {
                        @UniqueConstraint(name = "uk_tten_courseservice_program_table_program_name", columnNames = { "program_name" }) })
public class Program {

    @Column(name = "program_name")
    private String programName;
    //other attributes and getter setters. 
}

那么我在这里缺少什么?我试过放置:

catch(PSQLexception e)

但它没有捕获我的错误,因为它不是根异常。 DataIntegrityException有非常模糊的信息,如:

could not execute statement; SQL [n/a]; constraint [uk_tten_courseservice_program_table_program_name]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement

还有其他方法可以实现这些目标吗?我知道的一种方法是在保存每条记录之前对数据库运行搜索查询以检查它是否已存在,但我认为它不会有效。提前致谢。

1 个答案:

答案 0 :(得分:1)

要处理此类异常,您可以实施ExceptionHandler。要获得异常的根本原因,您可以使用实用程序方法org.springframework.core.NestedExceptionUtils#getMostSpecificCause

示例:

@ControllerAdvice
public class ExceptionHandler {

    @ExceptionHandler(DataIntegrityViolationException.class)
    public ResponseEntity<?> conflict(DataIntegrityViolationException e) {

        String message = NestedExceptionUtils.getMostSpecificCause(e).getMessage();
        ErrorMessage errorMessage = new ErrorMessage(message); 
        return new ResponseEntity<>(errorMessage), HttpStatus.CONFLICT);
    }
}

ErrorMessage是您的自定义错误消息类。

其他信息:https://www.toptal.com/java/spring-boot-rest-api-error-handling