【问题标题】:Using JOOQ, how do you map an SQLException to a business exception?使用 JOOQ,如何将 SQLException 映射到业务异常?
【发布时间】:2017-12-27 13:57:28
【问题描述】:

我正在使用 JOOQ,并且想将某些 SQLExceptions 映射到业务异常。 exception handling 文档页面说:

以下关于执行侦听器的部分记录了覆盖 jOOQ 异常处理的方法,如果您希望单独处理某些类型的约束违规,或者如果您从数据库中引发业务错误等。

但是,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()));
    }
}

【问题讨论】:

    标签: java sql jdbc jooq


    【解决方案1】:

    恐怕您必须自己完成这项工作。这就是为什么...

    使用 ExecuteListener 对你不起作用

    如果您想要 jOOQ 的 DataAccessException 的替代例外,则选择 ExecuteListener 以自动和全局翻译 SQLException 的路线很有用 - 例如Spring 的 DataAccessException 用于进一步处理 (example translator here)。它不适合自动将约束违规异常重新连接到特定的“业务异常”,因为ExecuteListener(作为全局参与者)不知道在什么上下文中可能发生了约束违规。可能有:

    • 导致违反约束的错误(例如,您应该更新,而不是插入)
    • 导致违反约束的用户错误(例如,用户提交了两次表单)
    • 导致违反约束的实际业务规则(例如检查约束)

    恐怕您必须为每个查询单独决定这一点。 ExecuteListener 仅帮助您重新连接异常处理的技术部分。

    为什么手册会提到“业务错误”?

    你已经引用了手册:

    或者如果您从数据库中引发业务错误

    这些业务错误可能是您从数据库触发器引发的用户定义错误,例如,在这种情况下您不会收到违反约束的情况,而是直接来自数据库的有意义的业务错误。

    【讨论】:

    • 我可能不应该使用“业务例外”这个词,因为我觉得它引起了一些混乱。我不是指与业务逻辑相关的特定异常(例如“BasketEmptyExcetion”),而是特定 SQL 错误的异常(例如外键违规的唯一约束),以便可以更轻松地捕获和处理它们业务代码(而不是捕获 DataAccessException 并就地比较 SQL 状态)。但是为了说明的目的,假设我想抛出一个 Spring DataAccessException,我的问题中的两个示例中哪一个是正确的?
    • @Hexagone:在将异常转换为 Spring DataAccessException 的特定情况下,您可以在此处使用示例异常转换器:github.com/jOOQ/jOOQ/blob/master/jOOQ-examples/…。我会将其添加到答案中
    • 感谢@Lukas Eder,这完全回答了我的问题。如果这个例子也包含在文档的某个地方,也许会很方便。
    猜你喜欢
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    相关资源
    最近更新 更多