【问题标题】:JPA and JPQL: NoResultException when selecting from multiple tables where one value is nullJPA 和 JPQL:从一个值为空的多个表中选择时出现 NoResultException
【发布时间】:2011-12-21 11:07:48
【问题描述】:

我正在使用 Java EE 6 并使用 JPA 的 javax.persistence.Entitymanager 查询数据库。我有一个 JPQL 查询代码 sn-p,看起来像这样:

Query query = entityManager.createQuery("
    select A.propertyX, B.propertyY, C.propertyZ
    from TableA A, TableB B, TableC C
    where A.id = :id and B.id = A.id and C.type = B.type
");
query.setParameter("id", id);
Object[] result = (Object[]) query.getSingleResult();

propertyX/Y/X 都是对其他实体的引用。在我的例子中,TableA、TableB 和 TableC 中的匹配行都存在。对于匹配的行,TableA.propertyX 和 TableB.propertyY 保存值,而 TableC.propertyZ 为空(并且不是必需的)。

我希望它执行并返回一个 Object[] 数组,其中前两个元素(propertyX 和 propertyY)的值和第三个元素(propertyZ)的值为 null。

但是,当 propertyZ 为 null 时,会抛出 NoResultException。如果我更改数据以使 propertyZ 不为空,则查询将执行并返回一个值。

  • 这是预期的 JPQL 行为吗?
  • 如何确保查询的行为符合我最初的预期?

显而易见的解决方法是选择整个根实体而不是任何子属性,例如'C' 而不是 'C.propertyZ',然后从实体对象中获取属性。但是,我希望它能够按我的预期工作,而无需这样做。

【问题讨论】:

    标签: java jakarta-ee jpa jpql entitymanager


    【解决方案1】:

    如果对于 A 和 B 中的给定行,C 中存在 C.type = B.type 的行,但该行的 propertyZ 列为空,那么您的查询应该返回一条记录是对的.

    但是,如果对于 A 和 B 中的给定行,C 中没有 C.type = B.type 的匹配行,那么您的查询将不返回任何结果。这与JPQL无关,而与SQL有关

    如果您希望后一种情况仍然在 propertyZ 字段中返回 null 记录,则需要使用 OUTER JOINs

    HTH

    【讨论】:

    • 正如我在问题中所写:所有三个表都有 行匹配。但如果 C.propertyZ 为空,则查询失败。如果 C.propertyZ 为 not null,则查询成功返回某些内容。其他一切都保持不变。并且 C.propertyZ 不用于任何查询条件。
    • 不确定是什么原因造成的。实际的 SQL 查询与这个简化版本有多大不同?你能分享一下实际的查询吗?
    • 我的实际查询与此处使用的查询非常相似。我什至把它修改成和这里的一样,得到了相同的结果。
    猜你喜欢
    • 2013-12-02
    • 2011-04-03
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 2012-03-05
    • 2021-03-10
    • 2012-05-06
    • 2014-12-16
    相关资源
    最近更新 更多