【问题标题】:Can't get error message for PSQLException无法获得 PSQLException 的错误消息
【发布时间】:2018-09-22 20:33:16
【问题描述】:

我开发了一个 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

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

【问题讨论】:

  • 您能否提供引发异常的代码以及您在哪里捕获它?
  • 写repository.save()的时候违反了db约束,抛出异常。

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


【解决方案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

【讨论】:

  • 感谢您的回答。但我不明白这段代码放在哪里?
  • 在你的项目中))它是独立的类。在我提供的链接中查看更多示例...
  • 当然在我的项目中,但在哪一层?控制器、服务?
  • 在网络层(见ResponseEntity)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多