如何获取UniqueViolationException而不是org.postgresql.util.PSQLException(或DataIntegrityViolationException)?

问题描述 投票:0回答:1

我有Spring Boot(4),使用Postgres(9.4)和JPA Data。我有一个具有唯一约束的数据表:

 CREATE TABLE sys
(
  sys_id serial NOT NULL,
  name text NOT NULL,
  CONSTRAINT sys_pk PRIMARY KEY (sys_id),
  CONSTRAINT sys_name_unique UNIQUE (name)
)

并且我试图在控制器中编写代码以保存新的sys,但是当我测试保存非唯一名称时,我无法捕获UniqueValiationException。相反,我有一个postgrs错误:

org.postgresql.util.PSQLException:错误:重复的键值违反了唯一约束“ sys_name_unique”键(名称)=(名称)已经存在。在org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2310)〜[postgresql-9.4.1209.jre7.jar:9.4.1209.jre7]等

我看到该异常称为DataIntegrityViolationException。当我抓住它时,它就会被抓住。但是它不应该是UniqueViolationException吗?

我的Sys实体类看起来像这样:

@Entity
@Table(name = "sys") 
public class Sys implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sys_id")
    private Integer sysId;
    @Column(name = "name")
    private String name;

    public Sys() {
    }
 //getters and setter below

ModelException.java:

public class ModelException extends RuntimeException {

    private static final long serialVersionUID = -7808396136535585717L;

    private final String field;

    public ModelException(String field, String message) {
        super(message);
        this.field = field;
    }

    public String getField() {
        return field;
    }
}

UniqueViolationException.java:公共类UniqueViolationException扩展了ModelException {

    private static final long serialVersionUID = -2105504304295367749L;


    public UniqueViolationException(String field, String message) {
        super(field, message);
    }
}
postgresql exception spring-boot spring-data-jpa
1个回答
1
投票

您可以通过捕获PSQLException并查看其错误代码来实现此目的。

catch (PSQLException e) {
    /*
     * "23505" is the state that indicates Unique Constraint Violation
     * https://www.postgresql.org/docs/9.2/errcodes-appendix.html
     */
    if ("23505".equals(e.getSQLState())) {
        ServerErrorMessage postgresError = e.getServerErrorMessage();
        if (postgresError != null) {
            String constraint = postgresError.getConstraint();
            if ("yourTable_pkey".equalsIgnoreCase(constraint)) {
                // DO SOMETHING
            }
        }
    }  
}
© www.soinside.com 2019 - 2024. All rights reserved.