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

时间:2016-09-18 13:02:36

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

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

 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"   密钥(名称)=(namea)已存在。     at 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);
    }
}

1 个答案:

答案 0 :(得分: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
            }
        }
    }  
}