How do I count the number of rows returned by subquery?

后端 未结 2 416
隐瞒了意图╮
隐瞒了意图╮ 2020-12-15 07:37

I want to do something like this:

select count(*) from (select ...)

(As it would be in SQL), but in JPA.

Any ideas on how I would d

相关标签:
2条回答
  • 2020-12-15 07:59

    This should do the trick (If you want to use JPA criteria API):

    CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();  
    CriteriaQuery<Long> query = cb.createQuery(Long.class);
    
    Root<Entity> root = query.from(Entity.class);
    
    //Selecting the count
    query.select(cb.count(root));
    
    //Create your search criteria
    Criteria criteria = ...
    
    //Adding search criteria   
    query.where(criteria);
    
    Long count = getEntityManager().createQuery(query).getSingleResult();
    

    On the other hand, if you want to use JP-QL, the following code should do the trick:

    //Add the where condition to the end of the query
    Query query = getEntityManager().createQuery("select count(*) from Entity entity where...")
    Long count = query.getSingleResult();
    
    0 讨论(0)
  • 2020-12-15 08:12

    I stumbled upon this issue as well. I would ultimately like to execute the following JPQL:

    SELECT COUNT(u)
    FROM (
       SELECT DISTINCT u
       FROM User u
       JOIN u.roles r
       WHERE r.id IN (1)
    )
    

    But this wasn't possible, also not with criteria API. Research taught that this was just a design limitation in JPA. The JPA spec states that subqueries are only supported in WHERE and HAVING clauses (and thus not in the FROM).

    Rewriting the query in the following JPQL form:

    SELECT COUNT(u)
    FROM User u
    WHERE u IN (
       SELECT DISTINCT u
       FROM User u
       JOIN u.roles r
       WHERE r.id IN (1)
    )
    

    using the JPA Criteria API like as follows:

    CriteriaQuery<Long> query = cb.createQuery(Long.class);
    Root<User> u = query.from(User.class);
    Subquery<User> subquery = query.subquery(User.class);
    Root<User> u_ = subquery.from(User.class);
    subquery.select(u_).distinct(true).where(u_.join("roles").get("id").in(Arrays.asList(1L)));
    query.select(cb.count(u)).where(cb.in(u).value(subquery));
    Long count = entityManager.createQuery(query).getSingleResult();
    // ...
    

    has solved the functional requirement for me. This should also give you sufficient insight into solving your particular functional requirement.

    0 讨论(0)
提交回复
热议问题