private <C, X> Subquery<?> createCountSubQuery( Root<T> root, CriteriaQuery<Long> countQuery, Selections<T, C, X> selection, CriteriaBuilder builder, Specification<T> spec, List<Expression<?>> groupBy, Predicate having) { Subquery<?> subquery = countQuery.subquery(entityInformation.getIdType()); Root subRoot = subquery.from(entityInformation.getJavaType()); Expression[] select = selection.select(subRoot, (AbstractQuery<C>) subquery, builder); subquery.select(select[0]); selection.join(subRoot, builder); Predicate predicate = builder.equal( subRoot.get(entityInformation.getIdAttribute()), root.get(entityInformation.getIdAttribute())); if (predicate != null) { subquery.where(predicate); } if (groupBy != null) { subquery.groupBy(groupBy); } if (having != null) { subquery.having(having); } return subquery; }
@Override public <C, X> Page<C> findAll( Specification<T> spec, Class<C> clazz, Selections<T, C, X> selection, Pageable pageable) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<C> query = builder.createQuery(clazz); Root<T> root = query.from(getDomainClass()); Predicate predicate = spec.toPredicate(root, query, builder); if (predicate != null) { query.where(predicate); } query.select(builder.construct(clazz, selection.select(root, query, builder))); List<Expression<?>> groupBy = query.getGroupList(); Predicate having = query.getGroupRestriction(); if (pageable.getSort() != null) { query.orderBy(toOrders(pageable.getSort(), root, builder)); } TypedQuery<C> typeQuery = em.createQuery(query); return pageable == null ? new PageImpl<>(typeQuery.getResultList()) : readPage(typeQuery, pageable, spec, selection, groupBy, having); }