title: Get collection count instead of the collection in JPA Criteria API?
body: <p>Lets say I have an entity:</p>
  
  <pre><code>@Entity
  public class Person {
  
      @Id
      @GeneratedValue
      private Long id;
  
      @ManyToMany(fetch = FetchType.LAZY)
      private List&lt;Role&gt; roles;
  
      @ManyToMany(fetch = FetchType.LAZY)
      private List&lt;Permission&gt; permissions;
      // etc
      // other fields here
  }
  </code></pre>
  
  <p>I want a to build a query using the Criteria API that filters these users and shows a list of people and among other info from the entity - how many roles does a person have.</p>
  
  <pre><code>CriteriaBuilder builder = em.getCriteriaBuilder();
  CriteriaQuery&lt;Person&gt; query = builder.createQuery(Person.class);
  Root&lt;Person&gt; personRoot = query.from(Person.class);
  // predicates here
  </code></pre>
  
  <p>However, this limits me to returning only a list of <code>Person</code> entities. I can always add a <code>@Transient</code> field to the entity, but this seems ugly since I might have many different queries and might end up with many such fields.</p>
  
  <p>On the other hand - I cant use <code>HQL</code> and write the query since I want complex filtering and I would have to deal with appending and removing things from the <code>HQL</code> query.</p>
  
  <p>My question, besides the one in the title of this post is this: how do I query the database using the Criteria API and return a non-entity (in case I want to filter the Person table but return only the number of roles, permissions, etc) and how do I do it for something very close to the actual entity (like the example with the role counter instead of the roles collection)?</p>
  
  <p><strong>UPDATE</strong>
  Using Hibernate's projections I came up with this. But still don't know that to write in <code>TODO</code>. <code>Projections.count</code> doesn't work since it excpects some kind of grouping, and I don't seem to be able to find any examples in the <code>Hibernate</code> documentation.</p>
  
  <pre><code>Criteria cr = session.createCriteria(Person.class);
  
  if (id != null) {
      cr.add(Restrictions.eq("id", id));
  }
  
  ProjectionList projectionList = Projections.projectionList();
  projectionList.add(Projections.property("id"), "id");
  projectionList.add(TODO, "rolesCount");
  </code></pre>