考虑一个假设的User
表:
-- postgres, but it could have been any other SQL database
CREATE TABLE User(
id SERIAL PRIMARY KEY,
mail VARCHAR(32) UNIQUE NOT NULL
);
假设我尝试使用相同的邮件添加两个用户:
session.save(new User(1, "xpto@gmail.com"));
session.save(new User(2, "xpto@gmail.com"));
并通过Hibernate执行它。 Hibernate会给我一个ConstraintViolationException
:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
...
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "users_mail_key"
Detail: Key (mail)=(xpto@gmail.com) already exists.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
...
我想知道的是,除了必须手动解析Exception的输出文本之外,还有一些好的方法,以收集错误的原因,以便我可以正确解释并对问题作出反应。
我意识到这实际上可能更像是Postgres Driver的问题,而不是实际的Hibernate问题,但我不确定这个阶段,所以我认为在Hibernate的背景下提问可能是恰当的。
答案 0 :(得分:1)
因此,如果您能够从getSQLState获取值,则可以处理异常:
" PostgreSQL服务器发出的所有消息都被分配了五个字符的错误代码,这些代码遵循SQL标准的约定,用于" SQLSTATE"码。需要知道发生了哪种错误情况的应用程序通常应该测试错误代码,而不是查看文本错误消息。"
来自:http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
23505 = unique_violation
注意:在此链接中还有列表。
答案 1 :(得分:0)
好吧,看了Postgres Driver的源代码后,问题似乎在于Postgres,而不是Hibernate。 PSQLException
将包含一些信息,尽管它并不像我最初想象的那样精致:(
} catch (PSQLException e) {
ServerErrorMessage m = e.getServerErrorMessage();
System.out.println(m.getColumn());
System.out.println(m.getConstraint());
System.out.println(m.getDatatype());
System.out.println(m.getDetail());
System.out.println(m.getFile());
System.out.println(m.getHint());
System.out.println(m.getInternalPosition());
System.out.println(m.getInternalQuery());
System.out.println(m.getLine());
System.out.println(m.getMessage());
System.out.println(m.getPosition());
System.out.println(m.getRoutine());
System.out.println(m.getSchema());
System.out.println(m.getSeverity());
System.out.println(m.getSQLState());
System.out.println(m.getTable());
System.out.println(m.getWhere());
}
打印
null
users_mail_key
null
Key (mail)=(xpto@gmail.com) already exists.
nbtinsert.c
null
0
null
398
duplicate key value violates unique constraint "users_mail_key"
0
_bt_check_unique
public
ERROR
23505
users
null