使用 JOOQ,如何将 SQLException 映射到业务异常?
Using JOOQ, how do you map an SQLException to a business exception?
我正在使用 JOOQ,并希望将某些 SQLExceptions 映射到业务异常。 exception handling 文档页面说:
The following section about execute listeners documents means of overriding jOOQ's exception handling, if you wish to deal separately with some types of constraint violations, or if you raise business errors from your database, etc.
但是the page about execute listeners上没有实际的例子。
我知道我必须实现 ExecuteListener
的方法 exception(ExecuteContext)
,但我不清楚我是否应该 throw
另一个例外,还是使用 ExecuteContext.exception
方法来覆盖现有的异常。例如
@Override
public void exception(ExecuteContext ctx) {
if (ctx.sqlException().getSQLState().equals("23503")) {
throw new ForeignKeyViolationException("Foreign key violation", ctx.sqlException());
}
}
或者:
@Override
public void exception(ExecuteContext ctx) {
if (ctx.sqlException().getSQLState().equals("23503")) {
ctx.exception(ForeignKeyViolationException("Foreign key violation", ctx.sqlException()));
}
}
恐怕,您必须自己完成这项工作。这就是为什么...
使用 ExecuteListener 对您不起作用
如果您想要 jOOQ 的 DataAccessException
- e.g. Spring's DataAccessException
for further processing (example translator here 的替代例外,选择 ExecuteListener
以自动和全局翻译 SQLException
的路线很有用。它不适合自动将违反约束的异常重新连接到特定的 "business exception",因为 ExecuteListener
(作为全局参与者)不知道在什么上下文中可能发生了约束违反。可能有:
- 导致违反约束的错误(例如,您应该更新而不是插入)
- 导致违反约束的用户错误(例如,用户提交了两次表单)
- 导致约束违规的实际业务规则(例如检查约束)
恐怕您必须针对每个查询单独决定这一点。 ExecuteListener
仅帮助您重新连接异常处理的技术部分。
手册为什么提到 "business errors"?
您引用了手册:
or if you raise business errors from your database
这些业务错误可能是您从数据库触发器引发的用户定义错误,例如,在这种情况下您不会收到约束冲突,而是直接从数据库中收到有意义的业务错误。
我正在使用 JOOQ,并希望将某些 SQLExceptions 映射到业务异常。 exception handling 文档页面说:
The following section about execute listeners documents means of overriding jOOQ's exception handling, if you wish to deal separately with some types of constraint violations, or if you raise business errors from your database, etc.
但是the page about execute listeners上没有实际的例子。
我知道我必须实现 ExecuteListener
的方法 exception(ExecuteContext)
,但我不清楚我是否应该 throw
另一个例外,还是使用 ExecuteContext.exception
方法来覆盖现有的异常。例如
@Override
public void exception(ExecuteContext ctx) {
if (ctx.sqlException().getSQLState().equals("23503")) {
throw new ForeignKeyViolationException("Foreign key violation", ctx.sqlException());
}
}
或者:
@Override
public void exception(ExecuteContext ctx) {
if (ctx.sqlException().getSQLState().equals("23503")) {
ctx.exception(ForeignKeyViolationException("Foreign key violation", ctx.sqlException()));
}
}
恐怕,您必须自己完成这项工作。这就是为什么...
使用 ExecuteListener 对您不起作用
如果您想要 jOOQ 的 DataAccessException
- e.g. Spring's DataAccessException
for further processing (example translator here 的替代例外,选择 ExecuteListener
以自动和全局翻译 SQLException
的路线很有用。它不适合自动将违反约束的异常重新连接到特定的 "business exception",因为 ExecuteListener
(作为全局参与者)不知道在什么上下文中可能发生了约束违反。可能有:
- 导致违反约束的错误(例如,您应该更新而不是插入)
- 导致违反约束的用户错误(例如,用户提交了两次表单)
- 导致约束违规的实际业务规则(例如检查约束)
恐怕您必须针对每个查询单独决定这一点。 ExecuteListener
仅帮助您重新连接异常处理的技术部分。
手册为什么提到 "business errors"?
您引用了手册:
or if you raise business errors from your database
这些业务错误可能是您从数据库触发器引发的用户定义错误,例如,在这种情况下您不会收到约束冲突,而是直接从数据库中收到有意义的业务错误。