argos/dmp-backend/src/main/java/eu/eudat/queryable/hibernatequeryablelist/QueryableHibernateList.java

140 lines
4.8 KiB
Java
Raw Normal View History

package eu.eudat.queryable.hibernatequeryablelist;
2018-01-02 09:36:40 +01:00
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;
2018-01-02 09:36:40 +01:00
import java.util.Set;
import java.util.stream.Collectors;
2018-01-02 09:36:40 +01:00
public class QueryableHibernateList<T extends DataEntity<T>> implements QueryableList<T> {
private EntityManager manager;
private CriteriaQuery<T> query;
private Class<T> tClass;
private Root<T> root;
private LinkedList<Predicate> predicates = new LinkedList<Predicate>();
private Integer length;
private Integer offset;
2018-01-02 09:36:40 +01:00
private Set<String> hints;
private String hint;
public QueryableHibernateList(EntityManager manager, Class<T> tClass) {
this.manager = manager;
this.tClass = tClass;
}
public QueryableHibernateList<T> setManager(EntityManager manager) {
this.manager = manager;
return this;
}
2018-01-02 09:36:40 +01:00
public void withHint(String hint){
this.hint = hint;
}
public QueryableList<T> setHints(Set<String> hints){
this.hints = hints;
return this;
}
public QueryableHibernateList<T> setEntity(Class<T> type) {
CriteriaBuilder builder = this.manager.getCriteriaBuilder();
this.query = builder.createQuery(type);
this.root = this.query.from(this.tClass);
return this;
}
public void initiateQueryableList(Class<T> type) {
CriteriaBuilder builder = this.manager.getCriteriaBuilder();
this.query = builder.createQuery(type);
}
@Override
public QueryableList<T> skip(Integer offset) {
this.offset = offset;
return this;
}
@Override
public QueryableList<T> take(Integer length) {
this.length = length;
return this;
}
public QueryableList<T> where(SinglePredicate<T> predicate) {
this.predicates.add(predicate.applyPredicate(this.manager.getCriteriaBuilder(), this.root));
return this;
}
public <R> List<R> select(SelectPredicate<T, R> predicate) {
List<T> list = this.toList();
List<R> newlist = new LinkedList<R>();
for (T item : list) {
newlist.add(predicate.applySelection(item));
}
return newlist;
}
public QueryableList<T> distinct() {
this.query.distinct(true);
return this;
}
2017-12-23 16:56:05 +01:00
public QueryableList<T> orderByAsc(OrderByPredicate<T> predicate) {
this.query.orderBy(this.manager.getCriteriaBuilder().desc(predicate.applyPredicate(this.root)));
return this;
}
public QueryableList<T> orderByDesc(OrderByPredicate<T> predicate) {
this.query.orderBy(this.manager.getCriteriaBuilder().asc(predicate.applyPredicate(this.root)));
return this;
}
2017-12-19 15:09:49 +01:00
public Long count(){
CriteriaBuilder criteriaBuilder = this.manager.getCriteriaBuilder();
CriteriaQuery<Long> 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<T> toList() {
Predicate[] array = new Predicate[this.predicates.size()];
this.predicates.toArray(array);
this.query.where(array);
TypedQuery<T> typedQuery = this.manager.createQuery(this.query);
if(this.offset!=null)typedQuery.setFirstResult(this.offset);
if(this.length!=null)typedQuery.setMaxResults(this.length);
2018-01-02 09:36:40 +01:00
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();
}
2018-01-02 09:36:40 +01:00
private TypedQuery<T> queryWithHint(List ids){
CriteriaBuilder criteriaBuilder = this.manager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(tClass);
Root<T> criteriaRoot = criteriaQuery.from(this.tClass);
criteriaQuery.where(criteriaRoot.get("id").in(ids));
TypedQuery<T> typedQuery = this.manager.createQuery(criteriaQuery);
typedQuery.setHint("javax.persistence.fetchgraph", this.manager.getEntityGraph(this.hint));
return typedQuery;
}
}