All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.thksystems.persistence.hibernate.BaseRepository Maven / Gradle / Ivy

/*
 * tksCommons / mugwort
 *
 * Author : Thomas Kuhlmann (ThK-Systems, http://oss.thk-systems.de) License : LGPL (https://www.gnu.org/licenses/lgpl.html)
 */
package de.thksystems.persistence.hibernate;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.LongType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

@SuppressWarnings("unchecked")
public abstract class BaseRepository {

    static final Logger LOG = LoggerFactory.getLogger(BaseRepository.class);
    protected Class entityType;
    @Autowired
    @PersistenceContext
    private EntityManager entityManager;

    public BaseRepository() {
        Type type = getClass().getGenericSuperclass();
        while (!(type instanceof ParameterizedType) || (((ParameterizedType) type).getRawType() != BaseRepository.class)) {
            if (type instanceof ParameterizedType) {
                type = ((Class) ((ParameterizedType) type).getRawType()).getGenericSuperclass();
            } else {
                type = ((Class) type).getGenericSuperclass();
            }
        }
        this.entityType = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
    }

    /**
     * Returns the current hibernate-session.
     */
    final Session getCurrentSession() {
        return entityManager.unwrap(Session.class);
    }

    /**
     * Get {@link Class} of the entity of this Dao.
     */
    Class getEntityType() {
        return entityType;
    }

    /**
     * Flush the whole session.
     */
    public void flush() {
        getCurrentSession().flush();
    }

    /**
     * Create entity.
     */
    public void create(E object) {
        getCurrentSession().save(object);
    }

    /**
     * Create or update ...
     */
    public void createOrUpdate(E object) {
        getCurrentSession().saveOrUpdate(object);
    }

    /**
     * Create {@link Criteria} for entity-type.
     */
    private Criteria distinctCriteria() {
        return getCurrentSession().createCriteria(getEntityType()).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
    }

    /**
     * Create {@link Criteria} with the given {@link Criterion}s.
     */
    private Criteria criteriaWithCriterions(Criterion... criterions) {
        Criteria criteria = distinctCriteria();
        for (Criterion criterion : criterions) {
            criteria.add(criterion);
        }
        return criteria;
    }

    /**
     * Find entity by id.
     */
    public E findById(long id) {
        return (E) getCurrentSession().get(getEntityType(), id);
    }

    /**
     * Query all entities with the given ids.
     */
    protected List queryByIds(List list) {
        return query(Restrictions.in("id", list));
    }

    /**
     * Query all - really all!!
     */
    public List queryAll() {
        return queryAll(new Order[0]);
    }

    /**
     * Query all - really all!! - using the given order.
     */
    public List queryAll(Order... orders) {
        Criteria criteria = distinctCriteria();
        for (Order order : orders) {
            criteria.addOrder(order);
        }
        return criteria.list();
    }

    /**
     * Find by using {@link Criterion}s.
     */
    protected E find(Criterion... criterions) {
        long startTime = System.currentTimeMillis();
        Criteria criteria = criteriaWithCriterions(criterions);
        E result = (E) criteria.uniqueResult();
        LOG.trace("Find for {} by {}. Runtime: {}", getEntityType(), criterions, System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Query by using {@link Criterion}s.
     */
    protected List query(Criterion... criterions) {
        long startTime = System.currentTimeMillis();
        Criteria criteria = criteriaWithCriterions(criterions);
        List list = criteria.list();
        LOG.trace("Query for {} by {}. Runtime: {}", getEntityType(), criterions, System.currentTimeMillis() - startTime);
        return list;
    }

    /**
     * Query by using {@link Criterion}s and an {@link Order}.
     */
    protected List query(Order order, Criterion... criterions) {
        long startTime = System.currentTimeMillis();
        Criteria criteria = criteriaWithCriterions(criterions);
        criteria.addOrder(order);
        List list = criteria.list();
        LOG.trace("Query for {} by {} order {}. Runtime: {}", getEntityType(), criterions, order, System.currentTimeMillis() - startTime);
        return list;
    }

    /**
     * Find by user-defined criteria.
     */
    protected E find(CriteriaModifier cm) {
        long startTime = System.currentTimeMillis();
        Criteria criteria = distinctCriteria();
        cm.modify(criteria);
        E result = (E) criteria.uniqueResult();
        LOG.trace("Find for {} by {}. Runtime: {}", getEntityType(), criteria, System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Query by user-defined criteria.
     */
    protected List query(CriteriaModifier cm) {
        long startTime = System.currentTimeMillis();
        Criteria criteria = distinctCriteria();
        cm.modify(criteria);
        List list = criteria.list();
        LOG.trace("Query for {} by {}. Runtime: {}", getEntityType(), criteria, System.currentTimeMillis() - startTime);
        return list;
    }

    /**
     * Find by example.
     */
    protected E find(E example) {
        long startTime = System.currentTimeMillis();
        Criteria criteria = distinctCriteria();
        E result = (E) criteria.add(Example.create(example)).uniqueResult();
        LOG.trace("Find for {} by {} (example). Runtime: {}", getEntityType(), criteria, System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Query by example.
     */
    protected List query(E example) {
        long startTime = System.currentTimeMillis();
        Criteria criteria = distinctCriteria();
        List list = criteria.add(Example.create(example)).list();
        LOG.trace("Query for {} by {} (example). Runtime: {}", getEntityType(), criteria, System.currentTimeMillis() - startTime);
        return list;
    }

    /**
     * Finds the entity by the given sql-query.
     *
     * @param sql    The SQL must return just the id-field aliased as 'id'.
     * @param params can be added by position '?' and a list of objects, or a single Map must be given.
     */
    protected E findBySqlUsingId(String sql, Object... params) {
        long startTime = System.currentTimeMillis();
        SQLQuery sqlQuery = createSqlUsingId(sql.toUpperCase(), params);
        long id = (long) sqlQuery.uniqueResult();
        E result = findById(id);
        LOG.trace("Find for {} by '{}'. Runtime: {}", getEntityType(), sql, System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Query entities by the given sql-query.
     *
     * @param sql    The SQL must return just the id-field aliased as 'id'.
     * @param params can be added by position '?' and a list of objects, or a single Map must be given.
     */
    protected List queryBySqlUsingId(String sql, Object... params) {
        long startTime = System.currentTimeMillis();
        SQLQuery sqlQuery = createSqlUsingId(sql.toUpperCase(), params);
        List list = sqlQuery.list();
        List resultList = queryByIds(list);
        LOG.trace("Query for {} by '{}'. Runtime: {}", getEntityType(), sql, System.currentTimeMillis() - startTime);
        return resultList;
    }

    private SQLQuery createSqlUsingId(String sql, Object... params) {
        SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql).addScalar("id", LongType.INSTANCE);
        setQueryParameter(sqlQuery, params);
        return sqlQuery;
    }

    private void setQueryParameter(Query query, Object... params) {
        if (params != null && params.length == 1 && params[0] instanceof Map) {
            Map paramMap = (Map) params[0];
            for (String key : paramMap.keySet()) {
                query.setParameter(key, paramMap.get(key));
            }
        } else {
            for (int i = 0; params != null && i < params.length; i++) {
                query.setParameter(i, params[i]);
            }
        }
    }

    /**
     * Finds the entity by the given hql-query.
     *
     * @param hql    HQL query string.
     * @param params can be added by position '?' and a list of objects, or a single Map must be given.
     */
    protected E findByHql(String hql, Object... params) {
        long startTime = System.currentTimeMillis();
        Query hqlQuery = createHql(hql, params);
        E result = (E) hqlQuery.uniqueResult();
        LOG.trace("Find for {} by '{}'. Runtime: {}", getEntityType(), hql, System.currentTimeMillis() - startTime);
        return result;
    }

    /**
     * Query entities by the given hql-query.
     *
     * @param hql    HQL query string.
     * @param params can be added by position '?' and a list of objects, or a single Map must be given.
     */
    protected List queryByHql(String hql, Object... params) {
        long startTime = System.currentTimeMillis();
        Query hqlQuery = createHql(hql, params);
        List list = hqlQuery.list();
        LOG.trace("Query for {} by '{}'. Runtime: {}", getEntityType(), hql, System.currentTimeMillis() - startTime);
        return list;
    }

    /**
     * Execute an update by the given hql.
     *
     * @param hql    HQL string.
     * @param params can be added by position '?' and a list of objects, or a single Map must be given.
     */
    protected int executeUpdatebyHql(String hql, Object... params) {
        long startTime = System.currentTimeMillis();
        Query hqlQuery = createHql(hql, params);
        int count = hqlQuery.executeUpdate();
        LOG.trace("Execute update of {} by '{}'. Runtime: {}", getEntityType(), hql, System.currentTimeMillis() - startTime);
        return count;
    }

    protected Query createHql(String hql, Object... params) {
        Query hqlQuery = getCurrentSession().createQuery(hql);
        setQueryParameter(hqlQuery, params);
        return hqlQuery;
    }

    protected interface CriteriaModifier {
        void modify(Criteria criteria);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy