diff --git a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java index 9c8cf6a992..143ec4521f 100755 --- a/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java +++ b/hibernate-entitymanager/src/main/java/org/hibernate/jpa/criteria/CriteriaQueryImpl.java @@ -26,6 +26,7 @@ package org.hibernate.jpa.criteria; import java.io.Serializable; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -43,6 +44,8 @@ import javax.persistence.metamodel.EntityType; import org.jboss.logging.Logger; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.jpa.internal.QueryImpl; import org.hibernate.jpa.criteria.compile.CompilableCriteria; import org.hibernate.jpa.criteria.compile.CriteriaInterpretation; @@ -76,9 +79,7 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< this.queryStructure = new QueryStructure( this, criteriaBuilder ); } - /** - * {@inheritDoc} - */ + @Override public Class getResultType() { return returnType; } @@ -86,24 +87,18 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< // SELECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery distinct(boolean applyDistinction) { queryStructure.setDistinct( applyDistinction ); return this; } - /** - * {@inheritDoc} - */ + @Override public boolean isDistinct() { return queryStructure.isDistinct(); } - /** - * {@inheritDoc} - */ + @Override @SuppressWarnings({ "unchecked" }) public Selection getSelection() { return ( Selection ) queryStructure.getSelection(); @@ -113,29 +108,25 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< queryStructure.setSelection( selection ); } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery select(Selection selection) { applySelection( selection ); return this; } - /** - * {@inheritDoc} - */ + @Override @SuppressWarnings({ "unchecked" }) public CriteriaQuery multiselect(Selection... selections) { return multiselect( Arrays.asList( selections ) ); } - /** - * {@inheritDoc} - */ + @Override @SuppressWarnings({ "unchecked" }) public CriteriaQuery multiselect(List> selections) { final Selection selection; + validateSelections( selections ); + if ( Tuple.class.isAssignableFrom( getResultType() ) ) { selection = ( Selection ) criteriaBuilder().tuple( selections ); } @@ -168,26 +159,34 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< return this; } + private void validateSelections(List> selections) { + // handle the requirement that we validate that the incoming selections do not contain + // duplicate aliases. + final HashSet aliases = new HashSet( CollectionHelper.determineProperSizing( selections.size() ) ); + for ( Selection selection : selections ) { + if ( StringHelper.isNotEmpty( selection.getAlias() ) ) { + boolean added = aliases.add( selection.getAlias() ); + if ( ! added ) { + throw new IllegalArgumentException( "Multi-select expressions defined duplicate alias : " + selection.getAlias() ); + } + } + } + } + // ROOTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public Set> getRoots() { return queryStructure.getRoots(); } - /** - * {@inheritDoc} - */ + @Override public Root from(EntityType entityType) { return queryStructure.from( entityType ); } - /** - * {@inheritDoc} - */ + @Override public Root from(Class entityClass) { return queryStructure.from( entityClass ); } @@ -195,24 +194,18 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< // RESTRICTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public Predicate getRestriction() { return queryStructure.getRestriction(); } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery where(Expression expression) { queryStructure.setRestriction( criteriaBuilder().wrap( expression ) ); return this; } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery where(Predicate... predicates) { // TODO : assuming this should be a conjuntion, but the spec does not say specifically... queryStructure.setRestriction( criteriaBuilder().and( predicates ) ); @@ -222,44 +215,35 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< // GROUPING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public List> getGroupList() { return queryStructure.getGroupings(); } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery groupBy(Expression... groupings) { queryStructure.setGroupings( groupings ); return this; } + @Override public CriteriaQuery groupBy(List> groupings) { queryStructure.setGroupings( groupings ); return this; } - /** - * {@inheritDoc} - */ + @Override public Predicate getGroupRestriction() { return queryStructure.getHaving(); } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery having(Expression expression) { queryStructure.setHaving( criteriaBuilder().wrap( expression ) ); return this; } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery having(Predicate... predicates) { queryStructure.setHaving( criteriaBuilder().and( predicates ) ); return this; @@ -268,16 +252,12 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< // ORDERING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public List getOrderList() { return orderSpecs; } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery orderBy(Order... orders) { if ( orders != null && orders.length > 0 ) { orderSpecs = Arrays.asList( orders ); @@ -288,28 +268,23 @@ public class CriteriaQueryImpl extends AbstractNode implements CriteriaQuery< return this; } - /** - * {@inheritDoc} - */ + @Override public CriteriaQuery orderBy(List orders) { orderSpecs = orders; return this; } - /** - * {@inheritDoc} - */ + @Override public Set> getParameters() { return queryStructure.getParameters(); } - /** - * {@inheritDoc} - */ + @Override public Subquery subquery(Class subqueryType) { return queryStructure.subquery( subqueryType ); } + @Override public void validate() { // getRoots() is explicitly supposed to return empty if none defined, no need to check for null if ( getRoots().isEmpty() ) {