JPA:TypedQuery有时返回null而不是NoResultException

JPA:TypedQuery有时返回null而不是NoResultException,jpa,hql,jpa-2.0,Jpa,Hql,Jpa 2.0,通常我使用NoResultException返回一个“空”对象,例如空错误列表或新的BigInteger(“0”),如果我从TypedQuery中没有得到任何结果。现在,事实证明,这有时是行不通的。突然,getSingleResult()返回null而不是导致NoResultException,我不明白为什么。看看这个例子: public BigInteger pointsSumByAccountId(long accountId) { try { TypedQu

通常我使用NoResultException返回一个“空”对象,例如空错误列表或新的BigInteger(“0”),如果我从TypedQuery中没有得到任何结果。现在,事实证明,这有时是行不通的。突然,getSingleResult()返回null而不是导致NoResultException,我不明白为什么。看看这个例子:

public BigInteger pointsSumByAccountId(long accountId)
{
    try
    {
        TypedQuery<BigInteger> pointsQuery = entityManager.createNamedQuery(Points.SumByAccountId, BigInteger.class);
        pointsQuery.setParameter(Points.AccountIdParameter, accountId);

        return pointsQuery.getSingleResult();
    }
    catch (NoResultException e)
    {
        return new BigInteger("0");
    }
}

这对我来说似乎是正确的行为

当没有返回任何行时,将抛出
NoResultException
,但在您的案例中,
sum
只返回一行值为
null
的行。来自JPA 2.0规范:

如果使用了SUM、AVG、MAX或MIN,并且没有可用于聚合函数的值 应用时,聚合函数的结果为空

如果要获取
0
而不是
null
,请使用
coalesce

select coalesce(sum(p.value), 0) ...

我知道空集的平均值、最大值和最小值未定义,但空集的总和为0。我想知道为什么它们会失败。对于非空集,SUM、AVG、MAX或MIN也可以是0。返回null将确认空集。
/**
 * Execute a SELECT query that returns a single result.
 *
 * @return the result
 *
 * @throws NoResultException if there is no result
 * @throws NonUniqueResultException if more than one result
 * @throws IllegalStateException if called for a Java
 * Persistence query language UPDATE or DELETE statement
 * @throws QueryTimeoutException if the query execution exceeds
 * the query timeout value set and only the statement is
 * rolled back
 * @throws TransactionRequiredException if a lock mode has
 * been set and there is no transaction
 * @throws PessimisticLockException if pessimistic locking
 * fails and the transaction is rolled back
 * @throws LockTimeoutException if pessimistic locking
 * fails and only the statement is rolled back
 * @throws PersistenceException if the query execution exceeds
 * the query timeout value set and the transaction
 * is rolled back
 */
X getSingleResult();
select coalesce(sum(p.value), 0) ...