package eu.eudat.queryable.hibernatequeryablelist; import eu.eudat.entities.DataEntity; import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.predicates.OrderByPredicate; import eu.eudat.queryable.predicates.SelectPredicate; import eu.eudat.queryable.predicates.SinglePredicate; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class QueryableHibernateList> implements QueryableList { private EntityManager manager; private CriteriaQuery query; private Class tClass; private Root root; private LinkedList predicates = new LinkedList(); private Integer length; private Integer offset; private Set hints; private String hint; public QueryableHibernateList(EntityManager manager, Class tClass) { this.manager = manager; this.tClass = tClass; } public QueryableHibernateList setManager(EntityManager manager) { this.manager = manager; return this; } public void withHint(String hint) { this.hint = hint; } public QueryableList setHints(Set hints) { this.hints = hints; return this; } public QueryableHibernateList setEntity(Class type) { CriteriaBuilder builder = this.manager.getCriteriaBuilder(); this.query = builder.createQuery(type); this.root = this.query.from(this.tClass); return this; } public void initiateQueryableList(Class type) { CriteriaBuilder builder = this.manager.getCriteriaBuilder(); this.query = builder.createQuery(type); } @Override public QueryableList skip(Integer offset) { this.offset = offset; return this; } @Override public QueryableList take(Integer length) { this.length = length; return this; } public QueryableList where(SinglePredicate predicate) { this.predicates.add(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.root)); return this; } public List select(SelectPredicate predicate) { List list = this.toList(); List newlist = new LinkedList(); for (T item : list) { newlist.add(predicate.applySelection(item)); } return newlist; } public QueryableList distinct() { this.query.distinct(true); return this; } public QueryableList orderByAsc(OrderByPredicate predicate) { this.query.orderBy(this.manager.getCriteriaBuilder().desc(predicate.applyPredicate(this.root))); return this; } public QueryableList orderByDesc(OrderByPredicate predicate) { this.query.orderBy(this.manager.getCriteriaBuilder().asc(predicate.applyPredicate(this.root))); return this; } public Long count() { CriteriaBuilder criteriaBuilder = this.manager.getCriteriaBuilder(); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Long.class); criteriaQuery.select(criteriaBuilder.count(criteriaQuery.from(this.tClass))); Predicate[] array = new Predicate[this.predicates.size()]; this.predicates.toArray(array); criteriaQuery.where(array); return this.manager.createQuery(criteriaQuery).getSingleResult(); } public List toList() { Predicate[] array = new Predicate[this.predicates.size()]; this.predicates.toArray(array); this.query.where(array); TypedQuery typedQuery = this.manager.createQuery(this.query); if (this.offset != null) typedQuery.setFirstResult(this.offset); if (this.length != null) typedQuery.setMaxResults(this.length); if (this.hint != null && this.hints.contains(hint)) { List ids = typedQuery.getResultList().stream().map(item -> item.getKeys()[0]).collect(Collectors.toList()); typedQuery = queryWithHint(ids); } return typedQuery.getResultList(); } private TypedQuery queryWithHint(List ids) { CriteriaBuilder criteriaBuilder = this.manager.getCriteriaBuilder(); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(tClass); Root criteriaRoot = criteriaQuery.from(this.tClass); criteriaQuery.where(criteriaRoot.get("id").in(ids)); TypedQuery typedQuery = this.manager.createQuery(criteriaQuery); typedQuery.setHint("javax.persistence.fetchgraph", this.manager.getEntityGraph(this.hint)); return typedQuery; } }