Skip to content

Instantly share code, notes, and snippets.

@cherniag
Created August 1, 2017 09:05
Show Gist options
  • Save cherniag/81d964c070052e5b949922d2812cf697 to your computer and use it in GitHub Desktop.
Save cherniag/81d964c070052e5b949922d2812cf697 to your computer and use it in GitHub Desktop.
multiselect
EntityManager em = getEntityManager();
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<StreamSource> criteriaQuery = criteriaBuilder.createQuery(Domain.class);
Root<StreamSource> source = criteriaQuery.from(Domain.class);
criteriaQuery
.multiselect(source.get("id"), source.get("name"), source.get("accountId"), source.get("description"),
source.get("enabled"), source.get("type"), source.get("subStorageType"), source.get("storageConfiguration"),
source.get("playbackMode"), source.get("live"), source.get("cacheable"),
source.joinList("linkedSources", JoinType.LEFT),
source.get("createdDate"))
.where(criteriaBuilder.equal(source.get("accountId"), accountId));
TypedQuery<Domain> query = em.createQuery(criteriaQuery);
((org.eclipse.persistence.jpa.JpaQuery)query).getDatabaseQuery().dontMaintainCache();
return query.getResultList();
Your query doesn't return a complete entity object as you're only selecting two fields of the given table (this is why you're getting an error that says yadayadapartialyadayada).
Your solution is almost right, here's what you need to change to make it work—making it partial.
Instead of a plain CriteriaQuery<...> you have to create a tuple CriteriaQuery<..> by calling CriteriaBuilder.createTupleQuery(). (Basically, you can call CriteriaBuilder.createQuery(...) and pass Tuple.class to it as an argument. Tuple is a sort of wildcard entity class.)
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq= cb.createTupleQuery();
Root<Documents> root = cq.from(Documents.class);
Expression<Integer> userId = root.get("USERID");
Expression<String> userType = root.get("USERTYPE");
Expression<Long> count = cb.count(userId);
cq.multiselect(userId.alias("USERID"), count.alias("CNT"));
cq.where(cb.equal(userType, "COMPANY");
cq.groupBy(userId);
cq.orderBy(cb.desc(count));
TypedQuery<Tuple> tq = em.createQuery(cq);
for (Tuple t : tq.getResultsList()) {
System.out.println(t.get("USERID"));
System.out.println(t.get("CNT"));
}
(Accessing fields of a Tuple gave me an error if I didn't use aliases for them (in multiselect(...)). This is why I've used aliases, but this can be tackled more cleanly by using JPA 2's Metamodel API, which is described in the specification quite thoroughly. )
The documentation for CriteriaQuery.multiselect(...) describes the behaviour of queries using Tuple objects more deeply.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment