Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA: TypedQuery sometimes returns null instead of NoResultException

Tags:

jpa

hql

jpa-2.0

Usually I work with NoResultException to return an "empty" object, e.g. an empty error list or new BigInteger("0"), if I get no results from a TypedQuery. Now it turned out that this sometimes doesn't work. Suddenly getSingleResult() returns null instead of causing a NoResultException, and I don't understand why. Look this example:

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");
    }
}

The important part of the Entity...

@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";
.
.
.

If I use an accountId which causes no results, I get null instead of NoResultException. Any ideas why this is so? Even Javadoc of TypedQuery says that it has to return 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();
like image 974
Bevor Avatar asked Apr 24 '12 09:04

Bevor


People also ask

Does JPA return null or empty list?

New! Save questions or answers and organize your favorite content. Learn more.

Does Crudrepository return null?

Returns: the saved entity; will never be null.

Can getResultList return null?

getResultList() returns an empty list instead of null . So check isEmpty() in the returned result, and continue with the rest of the logic if it is false. Save this answer.

What is query getSingleResult ()?

getSingleResult() Execute a SELECT query that returns a single untyped result. boolean.


1 Answers

It looks like a correct behaviour for me.

NoResultException is thrown when no rows are returned, but sum returns exactly one row with null value in your case. From JPA 2.0 Specification:

If SUM, AVG, MAX, or MIN is used, and there are no values to which the aggregate function can be applied, the result of the aggregate function is NULL.

If you want to get 0 instead of null, use coalesce:

select coalesce(sum(p.value), 0) ...
like image 130
axtavt Avatar answered Sep 22 '22 06:09

axtavt