AsyncProcessRepositoryImpl.java

package com.tradecloud.repository.async;

import com.tradecloud.domain.async.EntityType;
import com.tradecloud.domain.async.Process;
import com.tradecloud.domain.async.ProcessType;
import com.tradecloud.dto.async.ProcessSearch;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Repository(value = "asyncProcessRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class AsyncProcessRepositoryImpl extends RepositoryBaseImpl<Process, ProcessSearch> implements AsyncProcessRepository {

    private final long ONE_DAY = 1000 * 60 * 60 * 24;

    @Override
    public List<Process> search(ProcessSearch search) {
        //log.debug("Search. " + search);
        DetachedCriteria searchCriteria = DetachedCriteria.forClass(getPersistentClass(), "process");
        addSearchCriteria(searchCriteria, search);
        List<Process> list = getExecutableCriteriaList(searchCriteria, search.getSearchMetaParams());
        return list;
    }

    @Override
    public long count(ProcessSearch search) {
        DetachedCriteria searchCriteria = DetachedCriteria.forClass(getPersistentClass(), "process");
        addSearchCriteria(searchCriteria, search);
        return getExecutableCriteriaCount(searchCriteria);
    }

    protected void addSearchCriteria(DetachedCriteria searchCriteria, ProcessSearch search) {
        if (search.getProcessState() != null)
            searchCriteria.add(Restrictions.eq("processState", search.getProcessState()));
        if (search.getProcessType() != null)
            searchCriteria.add(Restrictions.eq("processType", search.getProcessType()));
        if (search.getExcludeProcessType() != null)
            searchCriteria.add(Restrictions.ne("processType", search.getExcludeProcessType()));
        if (search.isExactMatch()) {
            if (search.getUserName() != null)
                searchCriteria.add(Restrictions.eq("userName", search.getUserName()));
            if (search.getReference() != null)
                searchCriteria.add(Restrictions.eq("reference", search.getReference()));
            if (search.getRelatedEntityReference() != null)
                searchCriteria.add(Restrictions.eq("relatedEntityReference", search.getRelatedEntityReference()));
        } else {
            if (search.getUserName() != null)
                searchCriteria.add(Restrictions.ilike("userName", search.getUserName(), MatchMode.ANYWHERE));
            if (search.getReference() != null)
                searchCriteria.add(Restrictions.ilike("reference", search.getReference(), MatchMode.ANYWHERE));
            if (search.getRelatedEntityReference() != null)
                searchCriteria.add(Restrictions.ilike("relatedEntityReference", search.getRelatedEntityReference(), MatchMode.ANYWHERE));
        }
        if (search.getFromDate() != null)
            searchCriteria.add(Restrictions.gt("created", search.getFromDate()));
        if (search.getToDate() != null)
            searchCriteria.add(Restrictions.lt("created", getToDate(search.getToDate())));
        if (search.getEntityType() != null)
            searchCriteria.add(Restrictions.eq("entityType", search.getEntityType()));
        if (search.getEntityId() != null)
            searchCriteria.add(Restrictions.eq("entityId", search.getEntityId()));
    }

    private Date getToDate(Date toDate) {
        // Below will increase the 'toDate' value by one day seeing that, for
        // example: if one searches from '17-02-2014' to
        // '17-02-2014' that person would expect results for one day but,
        // without the below adjustment, would received no
        // results seeing that if the order was not created on '17-02-2014
        // 00:00:00' then the order would not be rendered.
        if (toDate != null) {
            return new Date(toDate.getTime() + ONE_DAY - 1000);
        }

        return toDate;
    }

    @Override
    public Process findLastProcess(Long entityId, EntityType entityType, ProcessType processType) {
        StringBuilder sql = new StringBuilder("SELECT c.* FROM process c WHERE 1=1 ");

        if (entityId != null) {
            sql.append("AND c.entityid = :entityId ");
        }
        if (entityType != null) {
            sql.append("AND c.entitytype = :entityType ");
        }
        if (processType != null) {
            sql.append("AND c.processtype = :processType ");
        }

        sql.append("ORDER BY c.created DESC LIMIT 1");

        var query = getCurrentSession()
                .createNativeQuery(sql.toString(), Process.class);

        if (entityId != null) {
            query.setParameter("entityId", entityId);
        }
        if (entityType != null) {
            query.setParameter("entityType", entityType.name());
        }
        if (processType != null) {
            query.setParameter("processType", processType.name());
        }

        return (Process) query.uniqueResult();
    }

    @Override
    public List<Process> searchByDateRange(Date from, Date to) {
        String queryStr = "select p from Process p where p.created>=:from and p.created<:to order by created asc";
        Query<Process> query = getCurrentSession().createQuery(queryStr, Process.class);
        query.setParameter("from", from);
        query.setParameter("to", to);
        return query.list();
    }
}