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

org.hibernate.internal.CriteriaImpl Maven / Gradle / Ivy

There is a newer version: 6.6.2.Final
Show newest version
/*
 * 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 .
 */
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 Criteria interface
 * @author Gavin King
 */
public class CriteriaImpl implements Criteria, Serializable {

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

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

	private List subcriteriaList = new ArrayList<>();

	private Map fetchModes = new HashMap<>();
	private Map 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 queryHints = new ArrayList();

	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 getLockModes() {
		return lockModes;
	}

	public Criteria getProjectionCriteria() {
		return projectionCriteria;
	}

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

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

	public Iterator 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 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();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy