我有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);
}
}
您可以通过捕获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
}
}
}
}