I use a criteriaBuilder to create a criteriaQuery for a specific type.
CriteriaQuery<? extends File> criteriaQuery = criteriaBuilder.createQuery(Folder.class);
The query is pretty complexe and I have to add multiple joins etc.
I need to limit the result of the query when I use the createQuery method of the entityManager.
final TypedQuery<? extends File> query = this.entityManager.createQuery(criteriaQuery)
.setFirstResult(start).setMaxResults(filePerPage);
But I also need to know how many results I can get without the limitation because I need it to calculate the number of page for a pagination system.
So I used another criteriaQueryObject to create a select count
CriteriaQuery<Long> criteriaQueryCount = criteriaBuilder.createQuery(Long.class);
It works but I have to apply the same joins and the same filters, so it's like I do the job twice.
For example :
//creation of the criteriaBuilders from specific types
CriteriaQuery<? extends File> criteriaQuery = criteriaBuilder.createQuery(Folder.class);
CriteriaQuery<Long> criteriaQueryCount = criteriaBuilder.createQuery(Long.class);
//creation of the roots
Root<? extends File> root = criteriaQuery.from(Folder.class),
rootCount = criteriaQuery.from(Folder.class);
//list of predicates feeded next
List<Predicate> criteriaList = new ArrayList<>(),
criteriaCountList = new ArrayList<>();
//adding a join and the predicates
CriteriaBuilder.In<Long> inTagIds = criteriaBuilder.in(root.join("tags", JoinType.INNER).get("id"));
CriteriaBuilder.In<Long> inTagIdsCount = criteriaBuilder.in(rootCount.join("tags", JoinType.INNER).get("id"));
tags.forEach(t -> {
inTagIds.value(t.getId());
inTagIdsCount.value(t.getId());
});
criteriaList.add(inTagIds);
criteriaCountList.add(inTagIds);
.... I have almost 10 others filters like this one.
//generating the requests
criteriaQuery.where(criteriaBuilder.and(criteriaList.toArray(new Predicate[0])));
criteriaQuery.distinct(true);
criteriaQueryCount.select(criteriaBuilder.count(rootCount));
criteriaQueryCount.where(criteriaBuilder.and(criteriaCountList.toArray(new Predicate[0])));
final TypedQuery<? extends File> query = this.entityManager.createQuery(criteriaQuery)
.setFirstResult(searchDto.start).setMaxResults(this.filePerPage);
Long count = this.entityManager.createQuery(criteriaQueryCount).getSingleResult();
List<? extends File> searchRs = query.getResultList();
My question is, is there a more convinient way to do that, I'd like to use the same CriteriaQuery object and/or the same root, is that possible ?
criteriaQuery, and you should easily see how to generify it to accomodate forcriteriaQueryCount. In the end, you'll only want to leavecriteriaBuilder.createQuery(...)andcriteriaQuery.select(...)out of that method - crizzis