【问题标题】:Why JPA uses javax.persistence.NoResultException为什么 JPA 使用 javax.persistence.NoResultException
【发布时间】:2025-12-15 09:35:01
【问题描述】:

javax.persistence.NoResultException的使用是不是违反了Java中异常使用的基本原则?

不应使用异常来控制程序的正常流程。在我看来,从数据库查询返回零结果似乎很标准(不是例外)情况。无论如何都将通过调用代码来处理。

【问题讨论】:

    标签: java jakarta-ee jpa


    【解决方案1】:

    请注意,javadoc for NoResultException 声明:

    在查询上执行 Query.getSingleResult() 或 TypedQuery.getSingleResult() 并且没有返回结果时由持久性提供程序抛出。

    使用getSingleResult() 表示您知道会有完全一个结果。不多(见NonUniqueResultException),不少。所以我认为没有结果确实是一种特殊情况。

    如果您不确定将返回的数据量,请使用getResultList()

    但是,您并不孤单对 JPA API 的这一部分感到厌恶。 This post 表示 getSingleResult() 唯一真正有效的用途是返回一个标量值,指出 NoResultException 是一个未经检查的异常并引用 Bloch 的 Effective Java,第 40 项:

    对可恢复的条件使用检查异常,对编程错误使用运行时异常。

    不幸的是,JPA 2.0 规范(或任何其他规范)没有解释这种选择背后的原因。

    【讨论】:

    • 完美的解释。我没有意识到我使用了getSingleResult()
    • 请注意,我个人不喜欢 API 的这一部分,因为它很容易出错。但这里的意图似乎很明确。
    • @mabi So I'd argue that the absence of a result is indeed an exceptional circumstance。恕我直言,这是最初的问题。
    • @j3ny4 是的,我对getSingleResult 的所有漫谈只是试图提供有关为什么首先存在此异常的上下文(因为这是引发它的唯一方法,AFAIK)
    • IMO 这是一个设计缺陷,没有找到 getSingleResult() 的东西应该是一个系统异常,就像它在 java EE 中的方式一样。这只是让异常完全无用,它所做的只是带走了一个非常好的异常名称。