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

com.github.fluent.hibernate.HibernateRequest Maven / Gradle / Ivy

package com.github.fluent.hibernate;

import java.util.Collection;
import java.util.List;

import javax.persistence.criteria.JoinType;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.ResultTransformer;

import com.github.fluent.hibernate.util.InternalUtils;

/**
 * @param 
 *            type of return value.
 * 
 * @author DoubleF1re
 * @author V.Ladynev
 */
public final class HibernateRequest {

    private final List restrictions = InternalUtils.CollectionUtils.newArrayList();

    private final ProjectionList projections = Projections.projectionList();

    private final Aliases aliases = Aliases.aliasList();

    private final List orders = InternalUtils.CollectionUtils.newArrayList();

    private String[] fetchJoinPaths;

    private boolean distinct;

    private ResultTransformer transformer;

    private final Class persistentClass;

    private Pagination pagination;

    private Integer maxResults;

    private HibernateRequest(Class persistentClass) {
        this.persistentClass = persistentClass;
    }

    public HibernateRequest idEq(Object value) {
        restrictions.add(Restrictions.idEq(value));
        return this;
    }

    public HibernateRequest eqOrIsNull(String propertyName, Object value) {
        restrictions.add(Restrictions.eqOrIsNull(propertyName, value));
        return this;
    }

    public HibernateRequest eq(String propertyName, Object value) {
        restrictions.add(Restrictions.eq(propertyName, value));
        return this;
    }

    public HibernateRequest ne(String propertyName, Object value) {
        restrictions.add(Restrictions.ne(propertyName, value));
        return this;
    }

    public HibernateRequest ge(String propertyName, Object value) {
        restrictions.add(Restrictions.ge(propertyName, value));
        return this;
    }

    public HibernateRequest gt(String propertyName, Object value) {
        restrictions.add(Restrictions.gt(propertyName, value));
        return this;
    }

    public HibernateRequest lt(String propertyName, Object value) {
        restrictions.add(Restrictions.lt(propertyName, value));
        return this;
    }

    public HibernateRequest le(String propertyName, Object value) {
        restrictions.add(Restrictions.le(propertyName, value));
        return this;
    }

    public HibernateRequest isNull(String propertyName) {
        restrictions.add(Restrictions.isNull(propertyName));
        return this;
    }

    public HibernateRequest isNotNull(String propertyName) {
        restrictions.add(Restrictions.isNotNull(propertyName));
        return this;
    }

    public HibernateRequest in(String propertyName, Collection values) {
        restrictions.add(Restrictions.in(propertyName, values));
        return this;
    }

    // TODO It works incorrectly for an only element array
    public HibernateRequest in(String propertyName, Object... values) {
        restrictions.add(Restrictions.in(propertyName, values));
        return this;
    }

    public HibernateRequest crit(Criterion criterion) {
        restrictions.add(criterion);
        return this;
    }

    public HibernateRequest proj(String propertyName) {
        proj(Projections.property(propertyName).as(propertyName));
        return this;
    }

    public HibernateRequest proj(String propertyName, String alias) {
        proj(Projections.property(propertyName).as(alias));
        return this;
    }

    // TODO pidProperty automatic detection name (may be impossible)
    public HibernateRequest projId(String pidProperty) {
        proj(Projections.id().as(pidProperty));
        return this;
    }

    public HibernateRequest projMin(String minProperty) {
        proj(Projections.min(minProperty));
        return this;
    }

    public HibernateRequest projMax(String maxProperty) {
        proj(Projections.max(maxProperty));
        return this;
    }

    public HibernateRequest proj(Projection projection) {
        projections.add(projection);
        return this;
    }

    public HibernateRequest distinct() {
        distinct = true;
        return this;
    }

    public HibernateRequest innerJoin(String associationPath) {
        innerJoin(associationPath, associationPath);
        return this;
    }

    public HibernateRequest innerJoin(String associationPath, String alias) {
        aliases.add(associationPath, alias, JoinType.INNER);
        return this;
    }

    public HibernateRequest innerJoin(String associationPath, String alias, Criterion withClause) {
        aliases.add(associationPath, alias, JoinType.INNER, withClause);
        return this;
    }

    public HibernateRequest leftJoin(String associationPath) {
        leftJoin(associationPath, associationPath);
        return this;
    }

    public HibernateRequest leftJoin(String associationPath, String alias) {
        aliases.add(associationPath, alias, JoinType.LEFT);
        return this;
    }

    public HibernateRequest leftJoin(String associationPath, String alias, Criterion withClause) {
        aliases.add(associationPath, alias, JoinType.LEFT, withClause);
        return this;
    }

    public HibernateRequest rightJoin(String associationPath) {
        rightJoin(associationPath, associationPath);
        return this;
    }

    public HibernateRequest rightJoin(String associationPath, String alias) {
        aliases.add(associationPath, alias, JoinType.RIGHT);
        return this;
    }

    public HibernateRequest rightJoin(String associationPath, String alias, Criterion withClause) {
        aliases.add(associationPath, alias, JoinType.RIGHT, withClause);
        return this;
    }

    public HibernateRequest transform(Class clazz) {
        transformer = new FluentHibernateResultTransformer(clazz);
        return this;
    }

    public HibernateRequest distinctToRootEntity() {
        this.transformer = Criteria.DISTINCT_ROOT_ENTITY;
        return this;
    }

    public HibernateRequest pagination(Pagination pagination) {
        this.pagination = pagination;
        return this;
    }

    public HibernateRequest maxResults(int maxResults) {
        this.maxResults = maxResults;
        return this;
    }

    /**
     * Sort from smallest to largest.
     */
    public HibernateRequest orderAsc(String propertyName) {
        orders.add(Order.asc(propertyName));
        return this;
    }

    /**
     * Sort from largest to smallest.
     */
    public HibernateRequest orderDesc(String propertyName) {
        orders.add(Order.desc(propertyName));
        return this;
    }

    // TODO It works incorrectly for an only element array
    public HibernateRequest fetchJoin(String... associationPaths) {
        fetchJoinPaths = associationPaths;
        return this;
    }

    public T first(T defaultValue) {
        T result = first();
        return result == null ? defaultValue : result;
    }

    public T first() {
        return InternalUtils.CollectionUtils. first(list());
    }

    @SuppressWarnings("unchecked")
    public List list() {
        return HibernateSessionFactory.doInTransaction(new IRequest>() {
            @Override
            public List doInTransaction(Session session) {
                return tuneCriteriaForList(createCriteria(session)).list();
            }
        });
    }

    // TODO may be return long?
    public int count() {
        Number result = HibernateSessionFactory.doInTransaction(new IRequest() {
            @Override
            public Number doInTransaction(Session session) {
                return (Number) count(createCriteria(session));
            }
        });
        return result == null ? 0 : result.intValue();
    }

    private Criteria createCriteria(Session session) {
        Criteria result = session.createCriteria(persistentClass);
        aliases.addToCriteria(result);

        for (Criterion restriction : restrictions) {
            result.add(restriction);
        }

        if (fetchJoinPaths != null) {
            for (String associationPath : fetchJoinPaths) {
                result.setFetchMode(associationPath, FetchMode.JOIN);
            }
        }

        return result;
    }

    private Criteria tuneCriteriaForList(Criteria criteria) {
        if (projections.getLength() > 0) {
            criteria.setProjection(distinct ? Projections.distinct(projections) : projections);
        }

        if (transformer != null) {
            criteria.setResultTransformer(transformer);
        }

        for (Order order : orders) {
            criteria.addOrder(order);
        }

        if (maxResults != null) {
            criteria.setMaxResults(maxResults);
        }

        // can replace maxResults
        if (pagination != null) {
            pagination.addToCriteria(criteria);
        }

        return criteria;
    }

    private Object count(Criteria criteria) {
        // TODO for requests with tables joins will be work incorrect
        // select count(*) from (select distinct pid1, pid2 from ...) check this
        criteria.setProjection(Projections.rowCount());
        return criteria.uniqueResult();
    }

    public static  HibernateRequest create(Class clazz) {
        return new HibernateRequest(clazz);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy