FINERACT-1724: Final touches for Client V2 search API
This commit is contained in:
committed by
Arnold Gálovics
parent
68c6053bd7
commit
fd27401de4
+67
-3
@@ -19,23 +19,35 @@
|
||||
package org.apache.fineract.infrastructure.core.jpa;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.support.PageableExecutionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CriteriaQueryFactory {
|
||||
|
||||
public List<Order> fromPageable(Pageable pageable, CriteriaBuilder cb, Root<?> root) {
|
||||
return fromPageable(pageable, cb, root, () -> null);
|
||||
private final EntityManager entityManager;
|
||||
|
||||
public List<Order> ordersFromPageable(Pageable pageable, CriteriaBuilder cb, Root<?> root) {
|
||||
return ordersFromPageable(pageable, cb, root, () -> null);
|
||||
}
|
||||
|
||||
public List<Order> fromPageable(Pageable pageable, CriteriaBuilder cb, Root<?> root, Supplier<Order> defaultOrderSupplier) {
|
||||
public List<Order> ordersFromPageable(Pageable pageable, CriteriaBuilder cb, Root<?> root, Supplier<Order> defaultOrderSupplier) {
|
||||
List<Order> orders = new ArrayList<>();
|
||||
Sort sort = pageable.getSort();
|
||||
if (sort.isSorted()) {
|
||||
@@ -54,4 +66,56 @@ public class CriteriaQueryFactory {
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
|
||||
public <S, U> Page<S> readPage(TypedQuery<S> query, Class<U> domainClass, Pageable pageable, Specification<U> spec) {
|
||||
|
||||
if (pageable.isPaged()) {
|
||||
query.setFirstResult((int) pageable.getOffset());
|
||||
query.setMaxResults(pageable.getPageSize());
|
||||
}
|
||||
|
||||
return PageableExecutionUtils.getPage(query.getResultList(), pageable, () -> executeCountQuery(getCountQuery(spec, domainClass)));
|
||||
}
|
||||
|
||||
private static long executeCountQuery(TypedQuery<Long> query) {
|
||||
List<Long> totals = query.getResultList();
|
||||
long total = 0L;
|
||||
|
||||
for (Long element : totals) {
|
||||
total += element == null ? 0 : element;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private <S> TypedQuery<Long> getCountQuery(Specification<S> spec, Class<S> domainClass) {
|
||||
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> query = builder.createQuery(Long.class);
|
||||
|
||||
Root<S> root = query.from(domainClass);
|
||||
|
||||
applySpecificationToCriteria(root, spec, query);
|
||||
|
||||
if (query.isDistinct()) {
|
||||
query.select(builder.countDistinct(root));
|
||||
} else {
|
||||
query.select(builder.count(root));
|
||||
}
|
||||
|
||||
// Remove all Orders the Specifications might have applied
|
||||
query.orderBy(Collections.emptyList());
|
||||
|
||||
return entityManager.createQuery(query);
|
||||
}
|
||||
|
||||
public <S, U> Root<U> applySpecificationToCriteria(Root<U> root, Specification<U> spec, CriteriaQuery<S> query) {
|
||||
|
||||
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
|
||||
Predicate predicate = spec.toPredicate(root, query, builder);
|
||||
|
||||
if (predicate != null) {
|
||||
query.where(predicate);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user