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

2023-12-20

通常我使用 NoResultException 返回一个“空”对象,例如如果我没有从 TypedQuery 中得到结果,则返回一个空错误列表或 new BigInteger("0")。现在事实证明,这有时行不通。突然 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");
    }
}

实体的重要组成部分...

@NamedQueries({@NamedQuery(name = "Points.sumByAccountId", query = "select sum(p.value) from Points p where p.validFrom <= current_timestamp() and p.validThru >= current_timestamp() and p.account.id = :accountId")})
public class Points
{
    private static final long serialVersionUID = -15545239875670390L;

    public static final String SumByAccountId = Points.class.getSimpleName() + ".sumByAccountId";
    public static final String AccountIdParameter = "accountId";
.
.
.

如果我使用导致没有结果的 accountId,我会得到 null 而不是 NoResultException。有什么想法为什么会这样吗?甚至 TypedQuery 的 Javadoc 也说它必须返回 NoResultException:

/**
 * 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();

对我来说这看起来是正确的行为。

NoResultException当没有返回行时抛出,但是sum返回恰好一行null在你的情况下的价值。来自 JPA 2.0 规范:

如果使用 SUM、AVG、MAX 或 MIN,并且没有可聚合函数的值 应用后,聚合函数的结果为 NULL。

如果你想得到0代替null, use coalesce:

select coalesce(sum(p.value), 0) ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JPA:TypedQuery 有时返回 null 而不是 NoResultException 的相关文章

随机推荐