org.hibernate.internal.CriteriaImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.internal.CriteriaImpl.java

Source

/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.internal;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.NaturalIdentifier;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.query.internal.AbstractProducedQuery;
import org.hibernate.sql.JoinType;
import org.hibernate.transform.ResultTransformer;

/**
 * Implementation of the <tt>Criteria</tt> interface
 * @author Gavin King
 */
public class CriteriaImpl implements Criteria, Serializable {

    private final String entityOrClassName;
    private transient SharedSessionContractImplementor session;
    private final String rootAlias;

    private List<CriterionEntry> criterionEntries = new ArrayList<>();
    private List<OrderEntry> orderEntries = new ArrayList<>();
    private Projection projection;
    private Criteria projectionCriteria;

    private List<Subcriteria> subcriteriaList = new ArrayList<>();

    private Map<String, FetchMode> fetchModes = new HashMap<>();
    private Map<String, LockMode> lockModes = new HashMap<>();

    private Integer maxResults;
    private Integer firstResult;
    private Integer timeout;
    private Integer fetchSize;

    private boolean cacheable;
    private String cacheRegion;
    private String comment;
    private final List<String> queryHints = new ArrayList<String>();

    private FlushMode flushMode;
    private CacheMode cacheMode;
    private FlushMode sessionFlushMode;
    private CacheMode sessionCacheMode;

    private Boolean readOnly;

    private ResultTransformer resultTransformer = Criteria.ROOT_ENTITY;

    // Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public CriteriaImpl(String entityOrClassName, SharedSessionContractImplementor session) {
        this(entityOrClassName, ROOT_ALIAS, session);
    }

    public CriteriaImpl(String entityOrClassName, String alias, SharedSessionContractImplementor session) {
        this.session = session;
        this.entityOrClassName = entityOrClassName;
        this.cacheable = false;
        this.rootAlias = alias;
    }

    @Override
    public String toString() {
        return "CriteriaImpl(" + entityOrClassName + ":" + (rootAlias == null ? "" : rootAlias)
                + subcriteriaList.toString() + criterionEntries.toString()
                + (projection == null ? "" : projection.toString()) + ')';
    }

    // State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public SharedSessionContractImplementor getSession() {
        return session;
    }

    public void setSession(SharedSessionContractImplementor session) {
        this.session = session;
    }

    public String getEntityOrClassName() {
        return entityOrClassName;
    }

    public Map<String, LockMode> getLockModes() {
        return lockModes;
    }

    public Criteria getProjectionCriteria() {
        return projectionCriteria;
    }

    public Iterator<Subcriteria> iterateSubcriteria() {
        return subcriteriaList.iterator();
    }

    public Iterator<CriterionEntry> iterateExpressionEntries() {
        return criterionEntries.iterator();
    }

    public Iterator<OrderEntry> iterateOrderings() {
        return orderEntries.iterator();
    }

    public Criteria add(Criteria criteriaInst, Criterion expression) {
        criterionEntries.add(new CriterionEntry(expression, criteriaInst));
        return this;
    }

    // Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public String getAlias() {
        return rootAlias;
    }

    public Projection getProjection() {
        return projection;
    }

    @Override
    public Criteria setProjection(Projection projection) {
        this.projection = projection;
        this.projectionCriteria = this;
        setResultTransformer(PROJECTION);
        return this;
    }

    @Override
    public Criteria add(Criterion expression) {
        add(this, expression);
        return this;
    }

    @Override
    public Criteria addOrder(Order ordering) {
        orderEntries.add(new OrderEntry(ordering, this));
        return this;
    }

    public FetchMode getFetchMode(String path) {
        return fetchModes.get(path);
    }

    @Override
    public Criteria setFetchMode(String associationPath, FetchMode mode) {
        String rootAliasPathPrefix = rootAlias + ".";
        if (rootAlias != null && !associationPath.startsWith(rootAliasPathPrefix)) {
            associationPath = rootAliasPathPrefix + associationPath;
        }
        fetchModes.put(associationPath, mode);
        return this;
    }

    @Override
    public Criteria setLockMode(LockMode lockMode) {
        return setLockMode(getAlias(), lockMode);
    }

    @Override
    public Criteria setLockMode(String alias, LockMode lockMode) {
        lockModes.put(alias, lockMode);
        return this;
    }

    @Override
    public Criteria createAlias(String associationPath, String alias) {
        return createAlias(associationPath, alias, JoinType.INNER_JOIN);
    }

    @Override
    public Criteria createAlias(String associationPath, String alias, JoinType joinType) {
        new Subcriteria(this, associationPath, alias, joinType);
        return this;
    }

    @Override
    public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
        return createAlias(associationPath, alias, JoinType.parse(joinType));
    }

    @Override
    public Criteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause) {
        new Subcriteria(this, associationPath, alias, joinType, withClause);
        return this;
    }

    @Override
    public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause)
            throws HibernateException {
        return createAlias(associationPath, alias, JoinType.parse(joinType), withClause);
    }

    @Override
    public Criteria createCriteria(String associationPath) {
        return createCriteria(associationPath, JoinType.INNER_JOIN);
    }

    @Override
    public Criteria createCriteria(String associationPath, JoinType joinType) {
        return new Subcriteria(this, associationPath, joinType);
    }

    @Override
    public Criteria createCriteria(String associationPath, int joinType) throws HibernateException {
        return createCriteria(associationPath, JoinType.parse(joinType));
    }

    @Override
    public Criteria createCriteria(String associationPath, String alias) {
        return createCriteria(associationPath, alias, JoinType.INNER_JOIN);
    }

    @Override
    public Criteria createCriteria(String associationPath, String alias, JoinType joinType) {
        return new Subcriteria(this, associationPath, alias, joinType);
    }

    @Override
    public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException {
        return createCriteria(associationPath, alias, JoinType.parse(joinType));
    }

    @Override
    public Criteria createCriteria(String associationPath, String alias, JoinType joinType, Criterion withClause) {
        return new Subcriteria(this, associationPath, alias, joinType, withClause);
    }

    @Override
    public Criteria createCriteria(String associationPath, String alias, int joinType, Criterion withClause)
            throws HibernateException {
        return createCriteria(associationPath, alias, JoinType.parse(joinType), withClause);
    }

    public ResultTransformer getResultTransformer() {
        return resultTransformer;
    }

    @Override
    public Criteria setResultTransformer(ResultTransformer tupleMapper) {
        this.resultTransformer = tupleMapper;
        return this;
    }

    public Integer getMaxResults() {
        return maxResults;
    }

    @Override
    public Criteria setMaxResults(int maxResults) {
        this.maxResults = maxResults;
        return this;
    }

    public Integer getFirstResult() {
        return firstResult;
    }

    @Override
    public Criteria setFirstResult(int firstResult) {
        this.firstResult = firstResult;
        return this;
    }

    public Integer getFetchSize() {
        return fetchSize;
    }

    @Override
    public Criteria setFetchSize(int fetchSize) {
        this.fetchSize = fetchSize;
        return this;
    }

    public Integer getTimeout() {
        return timeout;
    }

    @Override
    public Criteria setTimeout(int timeout) {
        this.timeout = timeout;
        return this;
    }

    @Override
    public boolean isReadOnlyInitialized() {
        return readOnly != null;
    }

    @Override
    public boolean isReadOnly() {
        if (!isReadOnlyInitialized() && getSession() == null) {
            throw new IllegalStateException(
                    "cannot determine readOnly/modifiable setting when it is not initialized and is not initialized and getSession() == null");
        }
        return (isReadOnlyInitialized() ? readOnly
                : getSession().getPersistenceContextInternal().isDefaultReadOnly());
    }

    @Override
    public Criteria setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
        return this;
    }

    public boolean getCacheable() {
        return this.cacheable;
    }

    @Override
    public Criteria setCacheable(boolean cacheable) {
        this.cacheable = cacheable;
        return this;
    }

    public String getCacheRegion() {
        return this.cacheRegion;
    }

    @Override
    public Criteria setCacheRegion(String cacheRegion) {
        this.cacheRegion = cacheRegion.trim();
        return this;
    }

    public String getComment() {
        return comment;
    }

    @Override
    public Criteria setComment(String comment) {
        this.comment = comment;
        return this;
    }

    public List<String> getQueryHints() {
        return queryHints;
    }

    @Override
    public Criteria addQueryHint(String queryHint) {
        queryHints.add(queryHint);
        return this;
    }

    @Override
    public Criteria setFlushMode(FlushMode flushMode) {
        this.flushMode = flushMode;
        return this;
    }

    @Override
    public Criteria setCacheMode(CacheMode cacheMode) {
        this.cacheMode = cacheMode;
        return this;
    }

    @Override
    public List list() throws HibernateException {
        before();
        try {
            return session.list(this);
        } finally {
            after();
        }
    }

    @Override
    public ScrollableResults scroll() {
        return scroll(session.getFactory().getDialect().defaultScrollMode());
    }

    @Override
    public ScrollableResults scroll(ScrollMode scrollMode) {
        before();
        try {
            return session.scroll(this, scrollMode);
        } finally {
            after();
        }
    }

    @Override
    public Object uniqueResult() throws HibernateException {
        return AbstractProducedQuery.uniqueElement(list());
    }

    protected void before() {
        if (flushMode != null) {
            sessionFlushMode = getSession().getHibernateFlushMode();
            getSession().setHibernateFlushMode(flushMode);
        }
        if (cacheMode != null) {
            sessionCacheMode = getSession().getCacheMode();
            getSession().setCacheMode(cacheMode);
        }
    }

    protected void after() {
        if (sessionFlushMode != null) {
            getSession().setHibernateFlushMode(sessionFlushMode);
            sessionFlushMode = null;
        }
        if (sessionCacheMode != null) {
            getSession().setCacheMode(sessionCacheMode);
            sessionCacheMode = null;
        }
    }

    public boolean isLookupByNaturalKey() {
        if (projection != null) {
            return false;
        }
        if (subcriteriaList.size() > 0) {
            return false;
        }
        if (criterionEntries.size() != 1) {
            return false;
        }
        CriterionEntry ce = criterionEntries.get(0);
        return ce.getCriterion() instanceof NaturalIdentifier;
    }

    // Inner classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public final class Subcriteria implements Criteria, Serializable {

        private String alias;
        private String path;
        private Criteria parent;
        private LockMode lockMode;
        private JoinType joinType = JoinType.INNER_JOIN;
        private Criterion withClause;
        private boolean hasRestriction;

        // Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        private Subcriteria(Criteria parent, String path, String alias, JoinType joinType, Criterion withClause) {
            this.alias = alias;
            this.path = path;
            this.parent = parent;
            this.joinType = joinType;
            this.withClause = withClause;
            this.hasRestriction = withClause != null;
            CriteriaImpl.this.subcriteriaList.add(this);
        }

        private Subcriteria(Criteria parent, String path, String alias, JoinType joinType) {
            this(parent, path, alias, joinType, null);
        }

        private Subcriteria(Criteria parent, String path, JoinType joinType) {
            this(parent, path, null, joinType);
        }

        @Override
        public String toString() {
            return "Subcriteria(" + path + ":" + (alias == null ? "" : alias) + ')';
        }

        // State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        @Override
        public String getAlias() {
            return alias;
        }

        public void setAlias(String alias) {
            this.alias = alias;
        }

        public String getPath() {
            return path;
        }

        public Criteria getParent() {
            return parent;
        }

        public LockMode getLockMode() {
            return lockMode;
        }

        @Override
        public Criteria setLockMode(LockMode lockMode) {
            this.lockMode = lockMode;
            return this;
        }

        public JoinType getJoinType() {
            return joinType;
        }

        public Criterion getWithClause() {
            return this.withClause;
        }

        public boolean hasRestriction() {
            return hasRestriction;
        }

        // Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        @Override
        public Criteria add(Criterion expression) {
            hasRestriction = true;
            CriteriaImpl.this.add(this, expression);
            return this;
        }

        @Override
        public Criteria addOrder(Order order) {
            CriteriaImpl.this.orderEntries.add(new OrderEntry(order, this));
            return this;
        }

        @Override
        public Criteria createAlias(String associationPath, String alias) {
            return createAlias(associationPath, alias, JoinType.INNER_JOIN);
        }

        @Override
        public Criteria createAlias(String associationPath, String alias, JoinType joinType)
                throws HibernateException {
            new Subcriteria(this, associationPath, alias, joinType);
            return this;
        }

        @Override
        public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
            return createAlias(associationPath, alias, JoinType.parse(joinType));
        }

        @Override
        public Criteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause)
                throws HibernateException {
            new Subcriteria(this, associationPath, alias, joinType, withClause);
            return this;
        }

        @Override
        public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause)
                throws HibernateException {
            return createAlias(associationPath, alias, JoinType.parse(joinType), withClause);
        }

        @Override
        public Criteria createCriteria(String associationPath) {
            return createCriteria(associationPath, JoinType.INNER_JOIN);
        }

        @Override
        public Criteria createCriteria(String associationPath, JoinType joinType) throws HibernateException {
            return new Subcriteria(Subcriteria.this, associationPath, joinType);
        }

        @Override
        public Criteria createCriteria(String associationPath, int joinType) throws HibernateException {
            return createCriteria(associationPath, JoinType.parse(joinType));
        }

        @Override
        public Criteria createCriteria(String associationPath, String alias) {
            return createCriteria(associationPath, alias, JoinType.INNER_JOIN);
        }

        @Override
        public Criteria createCriteria(String associationPath, String alias, JoinType joinType)
                throws HibernateException {
            return new Subcriteria(Subcriteria.this, associationPath, alias, joinType);
        }

        @Override
        public Criteria createCriteria(String associationPath, String alias, int joinType)
                throws HibernateException {
            return createCriteria(associationPath, alias, JoinType.parse(joinType));
        }

        @Override
        public Criteria createCriteria(String associationPath, String alias, JoinType joinType,
                Criterion withClause) throws HibernateException {
            return new Subcriteria(this, associationPath, alias, joinType, withClause);
        }

        @Override
        public Criteria createCriteria(String associationPath, String alias, int joinType, Criterion withClause)
                throws HibernateException {
            return createCriteria(associationPath, alias, JoinType.parse(joinType), withClause);
        }

        @Override
        public boolean isReadOnly() {
            return CriteriaImpl.this.isReadOnly();
        }

        @Override
        public boolean isReadOnlyInitialized() {
            return CriteriaImpl.this.isReadOnlyInitialized();
        }

        @Override
        public Criteria setReadOnly(boolean readOnly) {
            CriteriaImpl.this.setReadOnly(readOnly);
            return this;
        }

        @Override
        public Criteria setCacheable(boolean cacheable) {
            CriteriaImpl.this.setCacheable(cacheable);
            return this;
        }

        @Override
        public Criteria setCacheRegion(String cacheRegion) {
            CriteriaImpl.this.setCacheRegion(cacheRegion);
            return this;
        }

        @Override
        public List list() throws HibernateException {
            return CriteriaImpl.this.list();
        }

        @Override
        public ScrollableResults scroll() throws HibernateException {
            return CriteriaImpl.this.scroll();
        }

        @Override
        public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
            return CriteriaImpl.this.scroll(scrollMode);
        }

        @Override
        public Object uniqueResult() throws HibernateException {
            return CriteriaImpl.this.uniqueResult();
        }

        @Override
        public Criteria setFetchMode(String associationPath, FetchMode mode) {
            CriteriaImpl.this.setFetchMode(StringHelper.qualify(path, associationPath), mode);
            return this;
        }

        @Override
        public Criteria setFlushMode(FlushMode flushMode) {
            CriteriaImpl.this.setFlushMode(flushMode);
            return this;
        }

        @Override
        public Criteria setCacheMode(CacheMode cacheMode) {
            CriteriaImpl.this.setCacheMode(cacheMode);
            return this;
        }

        @Override
        public Criteria setFirstResult(int firstResult) {
            CriteriaImpl.this.setFirstResult(firstResult);
            return this;
        }

        @Override
        public Criteria setMaxResults(int maxResults) {
            CriteriaImpl.this.setMaxResults(maxResults);
            return this;
        }

        @Override
        public Criteria setTimeout(int timeout) {
            CriteriaImpl.this.setTimeout(timeout);
            return this;
        }

        @Override
        public Criteria setFetchSize(int fetchSize) {
            CriteriaImpl.this.setFetchSize(fetchSize);
            return this;
        }

        @Override
        public Criteria setLockMode(String alias, LockMode lockMode) {
            CriteriaImpl.this.setLockMode(alias, lockMode);
            return this;
        }

        @Override
        public Criteria setResultTransformer(ResultTransformer resultProcessor) {
            CriteriaImpl.this.setResultTransformer(resultProcessor);
            return this;
        }

        @Override
        public Criteria setComment(String comment) {
            CriteriaImpl.this.setComment(comment);
            return this;
        }

        @Override
        public Criteria addQueryHint(String queryHint) {
            CriteriaImpl.this.addQueryHint(queryHint);
            return this;
        }

        @Override
        public Criteria setProjection(Projection projection) {
            CriteriaImpl.this.projection = projection;
            CriteriaImpl.this.projectionCriteria = this;
            setResultTransformer(PROJECTION);
            return this;
        }
    }

    public static final class CriterionEntry implements Serializable {
        private final Criterion criterion;
        private final Criteria criteria;

        private CriterionEntry(Criterion criterion, Criteria criteria) {
            this.criteria = criteria;
            this.criterion = criterion;
        }

        public Criterion getCriterion() {
            return criterion;
        }

        public Criteria getCriteria() {
            return criteria;
        }

        @Override
        public String toString() {
            return criterion.toString();
        }
    }

    public static final class OrderEntry implements Serializable {
        private final Order order;
        private final Criteria criteria;

        private OrderEntry(Order order, Criteria criteria) {
            this.criteria = criteria;
            this.order = order;
        }

        public Order getOrder() {
            return order;
        }

        public Criteria getCriteria() {
            return criteria;
        }

        @Override
        public String toString() {
            return order.toString();
        }
    }
}