处理 Hibernate 的错误代码?
Handling Hibernate's error codes?
考虑一个假设 User
table:
-- 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)
...
我想知道的是,除了必须手动解析异常的输出文本之外,是否有一些好的方法来收集错误的原因,以便我可以正确地解释问题并对问题做出反应。
我意识到这实际上可能更多是 Postgres 驱动程序的问题,而不是 Hibernate 的问题,但我在这个阶段不确定,所以我认为在 Hibernate 的上下文中询问可能是合适的。
嗯,在查看 Postgres 驱动程序的源代码后,问题似乎出在 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
所以如果你能够从 getSQLState 中得到一个值,你就可以处理异常:
"All messages emitted by the PostgreSQL server are assigned five-character error codes that follow the SQL standard's conventions for "SQLSTATE" 代码。需要知道发生了哪种错误情况的应用程序通常应该测试错误代码,而不是查看文本错误消息。"
发件人:http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
23505 = unique_violation
注意:在这个 link 中还有列表。
考虑一个假设 User
table:
-- 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)
...
我想知道的是,除了必须手动解析异常的输出文本之外,是否有一些好的方法来收集错误的原因,以便我可以正确地解释问题并对问题做出反应。
我意识到这实际上可能更多是 Postgres 驱动程序的问题,而不是 Hibernate 的问题,但我在这个阶段不确定,所以我认为在 Hibernate 的上下文中询问可能是合适的。
嗯,在查看 Postgres 驱动程序的源代码后,问题似乎出在 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
所以如果你能够从 getSQLState 中得到一个值,你就可以处理异常:
"All messages emitted by the PostgreSQL server are assigned five-character error codes that follow the SQL standard's conventions for "SQLSTATE" 代码。需要知道发生了哪种错误情况的应用程序通常应该测试错误代码,而不是查看文本错误消息。"
发件人:http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html
23505 = unique_violation
注意:在这个 link 中还有列表。