Olinka
Olinka

Reputation: 23

Having count query with multiple join and predicate jpa

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

Answers (1)

Lunatic
Lunatic

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

Related Questions