Reputation: 23
In my persistence layer which is implemented generically i have fully workable method for left joining i.e
Join<?, ?> join = root.join(router, JoinType.LEFT);
map.forEach(
(u, v) -> unionPredicates
.add(join.on(criteriaBuilder.equal(join.get(u), v)).getOn()));
Where unionPredicates
is just predicate list with union condition but for counting with join requirement as
CriteriaQuery<Long> countCriteriaQuery = criteriaBuilder.createQuery(Long.class);
Root<R> countRoot = countCriteriaQuery.from(type);
entityManager.createQuery(countCriteriaQuery.select(criteriaBuilder
.count(countRoot))
.where(criteriaBuilder
.and(unionPredicates.toArray(new Predicate[]{})))).getSingleResult();
The return value is incorrect .
Upvotes: 2
Views: 715
Reputation: 1916
In your countRoot
you need to supply the join condition as well and has no idea about joins (with this shared snippet), one practice can be defining a list for saving routers and iterating elements on count clause .
private List<String> routers; //list of joining keys
Add routers in join method
this.routers.add(router);
Join<?, ?> join = root.join(router, JoinType.LEFT);
map.forEach(u, v) -> unionPredicates
.add(join.on(criteriaBuilder.equal(join.get(u), v)).getOn()));
Then supply the created list i.e routers
into count clause
CriteriaQuery<Long> countCriteriaQuery = criteriaBuilder.createQuery(Long.class);
Root<R> countRoot = countCriteriaQuery.from(type);
routers.forEach(o -> countRoot.join(o, JoinType.LEFT));
//rest of the code
Upvotes: 1