GenericFacade.java 3.96 KB
package fi.insomnia.bortal.facade;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.insomnia.bortal.model.ModelInterface;

/**
 * Session Bean implementation class GenericFacade
 */
public abstract class GenericFacade<PK, T extends ModelInterface> {

	private static final Logger logger = LoggerFactory.getLogger(GenericFacade.class);

	private final Class<T> entClass;

	public GenericFacade(Class<T> entityClass) {
		this.entClass = entityClass;
	}

	protected Class<T> getEntityClass() {
		return entClass;
	}

	protected abstract EntityManager getEm();

	public void create(T entity) {
		getEm().persist(entity);
	}

	public void remove(T entity) {
		getEm().remove(entity);
	}

	public T merge(T entity) {
		return getEm().merge(entity);

	}

	public T find(PK id) {
		if (id == null) {
			return null;
		}
		T ret = getEm().find(getEntityClass(), id);
		return ret;
	}

	public List<T> findAll() {
		return findAll(null);

	}

	public List<T> findAll(String sort) {
		return search(0, 0, null, null, sort);
	}

	public List<T> findRange(int[] range) {
		CriteriaQuery<T> cq = getEm().getCriteriaBuilder().createQuery(getEntityClass());
		cq.select(cq.from(getEntityClass()));
		TypedQuery<T> q = getEm().createQuery(cq);
		q.setMaxResults(range[1] - range[0]);
		q.setFirstResult(range[0]);
		return q.getResultList();
	}

	public long count() {
		CriteriaQuery<Long> cq = getEm().getCriteriaBuilder().createQuery(Long.class);
		Root<T> 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;
		try {
			ret = q.getSingleResult();
		} catch (NoResultException e) {
			ret = null;
		}
		return ret;
	}

	public void evict(T entity) {
		if (entity != null && entity.getId() != null) {
			getEm().getEntityManagerFactory().getCache().evict(getEntityClass(), entity.getId());
		}
	}

	protected List<T> search(String query, String[] fields, String orderfield) {
		return search(0, 0, query, fields, orderfield);
	}

	protected List<T> search(int page, int pagesize, String query, String[] fields, String orderfield) {

		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<T> cq = cb.createQuery(getEntityClass());

		Root<T> root = cq.from(getEntityClass());

		if (query != null && !query.isEmpty()) {
			addPredicates(cb, cq, root, query, fields);
		}

		if (orderfield != null) {
			cq.orderBy(cb.asc(root.get(orderfield)));
		}

		cq.select(root);
		TypedQuery<T> q = getEm().createQuery(cq);
		if (pagesize > 0) {
			logger.debug("Setting pagesize {} at facade", pagesize);
			q.setFirstResult(page * pagesize);
			q.setMaxResults(pagesize);

		}
		List<T> ret = q.getResultList();
		return ret;
	}

	protected long searchCount(String query, String[] fields) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
		Root<T> root = cq.from(getEntityClass());
		if (query != null && !query.isEmpty()) {
			addPredicates(cb, cq, root, query, fields);
		}

		cq.select(getEm().getCriteriaBuilder().count(root));
		TypedQuery<Long> q = getEm().createQuery(cq);
		return q.getSingleResult();
	}

	private void addPredicates(CriteriaBuilder cb, CriteriaQuery<?> cq, Root<T> root, String query, String[] fields) {
		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()])));

	}

}