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

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为null(并且不是必需的)。

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

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


这是预期的JPQL行为吗?
如何确保查询的行为与最初预期的一样?


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

最佳答案

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

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

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

高温超导

10-08 07:06