Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

What does EntityManager.getSingleResult() return for a COUNT query?

So.. what is the precise runtime type of foo?

Object foo = em.createQuery("SELECT COUNT(t) FROM com.company.Thing t WHERE prop = :param")
       .setParameter("param", value).getSingleResult();
  

4.8.4 Aggregate Functions in the SELECT Clause The result of a query

may be the result of an aggregate function applied to a path expression.

The following aggregate functions can be used in the SELECT clause of a query: AVG, COUNT, MAX, MIN, SUM.

For all aggregate functions except COUNT, the path expression that is the argument to the aggregate function must terminate in a state-field. The path expression argument to COUNT may terminate in either a state-field or a association-field, or the argument to COUNT may be an identification variable.

Arguments to the functions SUM and AVG must be numeric. Arguments to the functions MAX and MIN must correspond to orderable state-field types (i.e., numeric types, string types, character types, or date types).

The Java type that is contained in the result of a query using an aggregate function is as follows:

  • COUNT returns Long.
  • MAX, MIN return the type of the state-field to which they are applied.
  • AVG returns Double.
  • SUM returns Long when applied to state-fields of integral types (other than BigInteger); Double when applied to state-fields of floating point types; BigInteger when applied to state-fields of type BigInteger; and BigDecimal when applied to state-fields of type BigDecimal.
  • 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 COUNT is used, and there are no values to which COUNT can be applied, the result of the aggregate function is 0.

    The argument to an aggregate function may be preceded by the keyword DISTINCT to specify that duplicate values are to be eliminated before the aggregate function is applied.

    Null values are eliminated before the aggregate function is applied, regardless of whether the keyword DISTINCT is specified.

    When we use native query, then this method returns BigInteger instead of Long. Can anybody explain this behaviour? – Sumit Desai Feb 20, 2014 at 8:12

    NB : there's a difference between JQPL and Native query

    Query query = em.createQuery("SELECT COUNT(p) FROM PersonEntity p " );
    

    query.getSingleResult().getClass().getCanonicalName() --> java.lang.Long

    Query query = em.createNativeQuery("SELECT COUNT(*) FROM PERSON " );
    

    query.getSingleResult().getClass().getCanonicalName() --> java.math.BigInteger

    I used to do something like Integer.parseInt(q.getSingleResult().toString()); to keep my code "robust", but a cast to Number might be a cleaner solution... – mmey Oct 19, 2016 at 7:16

    COUNT(t) specifically returns java.lang.Long. When its appears on its own in this context it is returned as-is.

    (In other contexts the Long generated by COUNT may be wrapped, but not today.)

    second call to query.getSingleResult() will throw Exception Caused by: org.hibernate.SessionException: Session is closed!. Instead use Object obj = query.getSingleResult(); if (obj != null) { Integer result = Integer.parseInt(obj.toString()); return result; } return Integer.valueOf(0); – Mohammad Javed Jun 16, 2020 at 11:23

    Second call query.getSingleResult() will throw org.hibernate.SessionException: Session is closed!

    To avoid the org.hibernate.SessionException: Session is closed! use as below

    Object obj = query.getSingleResult();
        if (obj != null) {
            Integer result = Integer.parseInt(obj.toString());
            return result;
        return Integer.valueOf(0);
    

    Count returns long.

    Query query = em.createQuery("SELECT COUNT(*) FROM Mandate " );

    return (Long) query.getSingleResult();

    Mapped your entity with the Query.

    Welcome to SO. Please take a look at the other answers given already. I think, your one doesn't add anything new or improved to them. – ahuemmer Aug 1, 2022 at 7:00

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.