Commit a0a5e537 by Tuomas Riihimäki

add boolean isFullQuery to facade callbacks.

This allows callback class to decide if there is anything special to be done
with the query. For example we do not want sorting when counting objects. count() function
requires group by to be included on joined elements and if we are only sorting with
joined tables,
1 parent 306fca1d
Showing with 238 additions and 141 deletions
......@@ -45,7 +45,7 @@ public class AndPredicateCreator<A, T extends ModelInterface> implements FacadeC
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> root, List<Predicate> predicates, boolean isFullQuery) {
if (searchval == null || attributes == null || attributes.isEmpty()) {
return;
}
......
......@@ -39,7 +39,7 @@ public class EventLimiter implements FacadeCallback<EventUser> {
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) {
predicates.add(cb.equal(root.get(EventUser_.event), ev));
}
......
......@@ -45,7 +45,7 @@ public class EventUserAccountSaldoPredicate implements FacadeCallback<EventUser>
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) {
Subquery<BigDecimal> subq = cq.subquery(BigDecimal.class);
Root<AccountEvent> acRoot = subq.from(AccountEvent.class);
subq.where(cb.equal(acRoot.get(AccountEvent_.user), root));
......
......@@ -46,7 +46,7 @@ public class EventUserCardStateFilter implements FacadeCallback<EventUser> {
this.states = statelist;
}
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) {
if (states != null && !states.isEmpty())
{
for (CardState s : states)
......
......@@ -32,7 +32,7 @@ import fi.codecrew.moya.utilities.jpa.FacadeCallback;
public class EventUserPlacegroupPredicate implements FacadeCallback<EventUser> {
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) {
predicates.add(cb.isNotEmpty(root.get(EventUser_.groupMemberships)));
}
......
......@@ -66,7 +66,7 @@ public class EventUserRolefilter implements FacadeCallback<EventUser> {
return checkedRoles;
}
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) {
if (roles != null && !roles.isEmpty())
{
HashSet<Integer> roleids = new HashSet<Integer>();
......
......@@ -41,9 +41,9 @@ public class EventuserToUserWrapper implements FacadeCallback<EventUser> {
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<EventUser> root, List<Predicate> predicates, boolean isFullQuery) {
for (FacadeCallback<User> subcallback : callbacks) {
subcallback.exec(cb, cq, root.get(EventUser_.user), predicates);
subcallback.exec(cb, cq, root.get(EventUser_.user), predicates, isFullQuery);
}
}
......
......@@ -43,7 +43,7 @@ public class OrPredicateCreator<A, T extends ModelInterface> implements FacadeCa
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> root, List<Predicate> predicates, boolean isFullQuery) {
if (searchstr == null || attributes == null || attributes.isEmpty()) {
return;
}
......
......@@ -53,8 +53,10 @@ public class OrderCallback<T extends ModelInterface> implements FacadeCallback<T
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> root, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> root, List<Predicate> predicates, boolean isFullQuery) {
if (!isFullQuery)
return;
Class<?> rettype = cq.getResultType();
// Check if returntype is entity or are we for example counting results
if (!ModelInterface.class.isAssignableFrom(rettype)) {
......
......@@ -61,7 +61,7 @@ public abstract class PathStringSearchPredicateCreator<T extends ModelInterface,
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> path, List<Predicate> predicates) {
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<T> path, List<Predicate> predicates, boolean isFullQuery) {
if (searchstr == null || attributes == null || attributes.isEmpty()) {
return;
}
......
package fi.codecrew.moya.facade.callbacks.bill;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import fi.codecrew.moya.model.Bill;
import fi.codecrew.moya.model.Bill_;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.utilities.jpa.FacadeCallback;
public class BillEventPredicate implements FacadeCallback<Bill> {
private final LanEvent event;
public BillEventPredicate(LanEvent e) {
this.event = e;
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<Bill> root, List<Predicate> predicates, boolean isFullQuery) {
predicates.add(cb.equal(root.get(Bill_.event), event));
}
}
package fi.codecrew.moya.facade.callbacks.bill;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.metamodel.SingularAttribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.model.Bill;
import fi.codecrew.moya.model.Bill_;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.utilities.jpa.FacadeCallback;
public class BillFilterPredicate extends GenericBillPredicate {
private final Map<String, Object> filters;
private final LanEvent event;
private static final Logger logger = LoggerFactory.getLogger(BillFilterPredicate.class);
public BillFilterPredicate(LanEvent event, Map<String, Object> filters) {
this.filters = filters;
this.event = event;
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<Bill> root, List<Predicate> predicates, boolean isFullQuery) {
for (Entry<String, Object> f : filters.entrySet()) {
logger.info("f {} {}", f.getKey(), f.getValue());
SingularAttribute<? super Bill, ?> field = BILL_SEARCH_FIELDS.get(f.getKey());
Object val = f.getValue();
switch (f.getKey()) {
case "referenceNumber": {
if (f.getValue() == null || f.getValue().toString().length() < 2) {
continue;
}
try {
int ref = Bill.getBillnrFromReference(event, Integer.valueOf(f.getValue().toString()));
if (ref < 0)
continue;
val = Integer.valueOf(ref);
} catch (Exception e) {
logger.info("Exception while parsing referencenumber {}", val);
continue;
}
break;
}
default:
}
predicates.add(cb.equal(root.get(field), val));
}
}
}
package fi.codecrew.moya.facade.callbacks.bill;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.metamodel.SingularAttribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.entitysearch.BillSearchQuery;
import fi.codecrew.moya.model.Bill;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.EventUser_;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.model.User_;
import fi.codecrew.moya.utilities.SearchQuery.QuerySortOrder;
public class BillOrderPredicate extends GenericBillPredicate {
private final String sort;
private QuerySortOrder dir;
private static final Logger logger = LoggerFactory.getLogger(BillOrderPredicate.class);
public BillOrderPredicate(BillSearchQuery queryParams) {
this.sort = queryParams.getSort();
this.dir = queryParams.getSortDirection();
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<Bill> root, List<Predicate> predicates, boolean isFullQuery) {
if (!isFullQuery || dir == null || sort == null) {
return;
}
SingularAttribute<? super Bill, ?> s = BILL_SEARCH_FIELDS.get(sort);
if (s == null) {
logger.info("Not found bill sort!: {} dir {}", sort, dir);
return;
}
Path<?> path = root.get(s);
if (s.getJavaMember().getDeclaringClass().equals(EventUser.class)) {
path = ((Path<EventUser>) path).get(EventUser_.user).get(User_.login);
}
Order order = null;
switch (dir) {
case ASCENDING:
order = cb.asc(path);
break;
case DESCENDING:
order = cb.desc(path);
break;
default:
return;
}
cq.orderBy(order);
}
}
package fi.codecrew.moya.facade.callbacks.bill;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import fi.codecrew.moya.model.Bill;
import fi.codecrew.moya.model.Bill_;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.utilities.jpa.FacadeCallback;
public class BillUserPredicate implements FacadeCallback<Bill> {
private final EventUser user;
public BillUserPredicate(EventUser user) {
this.user = user;
}
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<Bill> root, List<Predicate> predicates, boolean isFullQuery) {
if (user != null) {
predicates.add(cb.equal(root.get(Bill_.user), user));
}
}
}
package fi.codecrew.moya.facade.callbacks.bill;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.metamodel.SingularAttribute;
import fi.codecrew.moya.model.Bill;
import fi.codecrew.moya.model.Bill_;
import fi.codecrew.moya.utilities.jpa.FacadeCallback;
public abstract class GenericBillPredicate implements FacadeCallback<Bill> {
public static final Map<String, SingularAttribute<? super Bill, ?>> BILL_SEARCH_FIELDS;
static {
HashMap<String, SingularAttribute<? super Bill, ?>> m = new HashMap<>();
m.put("address", Bill_.addr1);
m.put("billNumber", Bill_.billNumber);
m.put("user", Bill_.user);
m.put("sentDate", Bill_.sentDate);
m.put("payer", Bill_.user);
m.put("billNumber", Bill_.billNumber);
m.put("referenceNumber", Bill_.billNumber);
m.put("id", Bill_.id);
BILL_SEARCH_FIELDS = Collections.unmodifiableMap(m);
}
}
......@@ -30,5 +30,5 @@ public interface FacadeCallback<C extends ModelInterface> {
// void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Root<C> root,
// List<Predicate> predicates);
void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<C> root, List<Predicate> predicates);
void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Path<C> root, List<Predicate> predicates, boolean isFullQuery);
}
......@@ -39,9 +39,6 @@ public abstract class GenericFacade<C extends ModelInterface> {
private final Class<C> entClass;
// private static final Logger logger =
// LoggerFactory.getLogger(GenericFacade.class);
public GenericFacade(Class<C> entityClass) {
this.entClass = entityClass;
}
......@@ -115,35 +112,6 @@ public abstract class GenericFacade<C extends ModelInterface> {
* vain ko. tapahtumaan / käyttäjään / muuhun olioon liittyvät Jos oikeasti
* tarpeellinen luo funktio facadeen!
*/
// @Deprecated
// public List<C> findAll() {
// return findAll(null);
// }
//
// @Deprecated
// public List<C> findAll(String sort) {
// return findAll(0, 0, sort);
// }
//
// @Deprecated
// public List<C> findRange(int[] range) {
// CriteriaQuery<C> cq =
// getEm().getCriteriaBuilder().createQuery(getEntityClass());
// cq.select(cq.from(getEntityClass()));
// TypedQuery<C> q = getEm().createQuery(cq);
// q.setMaxResults(range[1] - range[0]);
// q.setFirstResult(range[0]);
// return q.getResultList();
// }
// @Deprecated
// public long count() {
// CriteriaQuery<Long> cq =
// getEm().getCriteriaBuilder().createQuery(Long.class);
// Root<C> rt = cq.from(getEntityClass());
// cq.select(getEm().getCriteriaBuilder().count(rt));
// TypedQuery<Long> q = getEm().createQuery(cq);
// return q.getSingleResult();
// }
protected static <K> K getSingleNullableResult(TypedQuery<K> q) {
K ret = null;
......@@ -155,21 +123,6 @@ public abstract class GenericFacade<C extends ModelInterface> {
return ret;
}
// @Deprecated
// protected List<C> search(String query, String[] fields, String
// orderfield) {
// return search(0, 0, query, fields, orderfield);
// }
//
// @Deprecated
// protected SearchResult<C> searcher(int page, int pagesize, String query,
// String[] fields, String orderfield) {
// SearchResult<C> ret = new SearchResult<C>();
// ret.setResults(search(page, pagesize, query, fields, orderfield));
// ret.setResultcount(searchCount(query, fields));
// return ret;
// }
// Le fu... Tuota.. generics ei hanskaa '...' operaattoria.. tehdään siis
// näin... :(
protected SearchResult<C> searcher(SearchQuery search, FacadeCallback<C> callback) {
......@@ -209,29 +162,28 @@ public abstract class GenericFacade<C extends ModelInterface> {
CriteriaQuery<C> listCQuery = cb.createQuery(getEntityClass());
CriteriaQuery<Long> countCQuery = cb.createQuery(Long.class);
searchCallbacks(listCQuery, list);
searchCallbacks(listCQuery, list, true);
Path<C> countRoot = searchCallbacks(countCQuery, list);
countCQuery.select(cb.count(countRoot));
Path<C> countRoot = searchCallbacks(countCQuery, list, false);
countCQuery.select(cb.count(countRoot.get(ModelInterface.ID_COLUMN)));
TypedQuery<Long> countQ = getEm().createQuery(countCQuery);
TypedQuery<C> listQ = getEm().createQuery(listCQuery);
if (search.getPagesize() > 0) {
listQ.setFirstResult(search.getPage() * search.getPagesize());
listQ.setMaxResults(search.getPagesize());
}
return new SearchResult<C>(listQ.getResultList(), countQ.getSingleResult());
}
protected From<?, C> searchCallbacks(CriteriaQuery<?> cq, List<FacadeCallback<C>> list) {
return searchCallbacks(cq, list, getEntityClass());
protected From<?, C> searchCallbacks(CriteriaQuery<?> cq, List<FacadeCallback<C>> list, boolean isFullQuery) {
return searchCallbacks(cq, list, getEntityClass(), isFullQuery);
}
protected <T extends ModelInterface> From<?, T> searchCallbacks(CriteriaQuery<?> cq, List<FacadeCallback<T>> list, Class<T> clazz) {
protected <T extends ModelInterface> From<?, T> searchCallbacks(CriteriaQuery<?> cq, List<FacadeCallback<T>> list, Class<T> clazz, boolean isFullQuery) {
Root<T> root = cq.from(clazz);
ArrayList<Predicate> predicates = handlePredicates(cq, list, root);
ArrayList<Predicate> predicates = handlePredicates(cq, list, root, isFullQuery);
if (!predicates.isEmpty()) {
Predicate[] preds = predicates.toArray(new Predicate[predicates.size()]);
cq.where(preds);
......@@ -241,91 +193,20 @@ public abstract class GenericFacade<C extends ModelInterface> {
}
protected <T extends ModelInterface> ArrayList<Predicate> handlePredicates(CriteriaQuery<?> cq, List<FacadeCallback<T>> list, From<?, T> root) {
protected <T extends ModelInterface> ArrayList<Predicate> handlePredicates(CriteriaQuery<?> cq, List<FacadeCallback<T>> list, From<?, T> root, boolean isFullQuery) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
ArrayList<Predicate> predicates = new ArrayList<Predicate>();
for (FacadeCallback<T> fc : list) {
if (fc != null) {
fc.exec(cb, cq, root, predicates);
fc.exec(cb, cq, root, predicates, isFullQuery);
}
}
return predicates;
}
// @Deprecated
// protected List<C> search(int page, int pagesize, String query, String[]
// fields, String orderfield) {
//
// CriteriaBuilder cb = getEm().getCriteriaBuilder();
// CriteriaQuery<C> cq = cb.createQuery(getEntityClass());
//
// Root<C> root = cq.from(getEntityClass());
//
// addPredicates(cq, root, query, fields);
//
// TypedQuery<C> q = getEm().createQuery(cq);
// if (pagesize > 0) {
// q.setFirstResult(page * pagesize);
// q.setMaxResults(pagesize);
//
// }
// List<C> ret = q.getResultList();
// return ret;
// }
//
// @Deprecated
// protected void addPredicates(CriteriaQuery<?> cq, Root<C> root, String
// query, String[] fields) {
// CriteriaBuilder cb = getEm().getCriteriaBuilder();
// if (query != null && !query.isEmpty() && fields != null && fields.length
// > 0) {
// List<Predicate> preds = new ArrayList<Predicate>();
// for (String field : fields) {
// Path<String> rootfield = root.get(field);
// preds.add(cb.like(cb.lower(rootfield), query));
// }
// cq.where(cb.or(preds.toArray(new Predicate[preds.size()])));
// }
//
// }
//
// @Deprecated
// protected long searchCount(String query, String[] fields) {
// CriteriaBuilder cb = getEm().getCriteriaBuilder();
// CriteriaQuery<Long> cq = cb.createQuery(Long.class);
// Root<C> root = cq.from(getEntityClass());
//
// addPredicates(cq, root, query, fields);
// cq.select(getEm().getCriteriaBuilder().count(root));
//
// TypedQuery<Long> q = getEm().createQuery(cq);
// return q.getSingleResult();
// }
// @Deprecated
// public List<C> findAll(int page, int pagesize, String sort) {
// CriteriaBuilder cb = getEm().getCriteriaBuilder();
// CriteriaQuery<C> cq = cb.createQuery(getEntityClass());
// Root<C> root = cq.from(getEntityClass());
//
// if (sort != null) {
// cq.orderBy(cb.asc(root.get(sort)));
// }
//
// cq.select(cq.from(getEntityClass()));
// TypedQuery<C> q = getEm().createQuery(cq);
//
// if (pagesize > 0) {
// q.setFirstResult(page * pagesize);
// q.setMaxResults(pagesize);
// }
//
// return q.getResultList();
// }
/**
* Synchronize the persistence context to the underlying database.
*
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!