HHH-8444 - Fix criteriaapi failures from JPA 2.1 TCK
This commit is contained in:
parent
b12ad4f5cc
commit
d5ceb60062
|
@ -26,6 +26,7 @@ package org.hibernate.jpa.criteria;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -43,6 +44,8 @@ import javax.persistence.metamodel.EntityType;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
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.internal.QueryImpl;
|
||||||
import org.hibernate.jpa.criteria.compile.CompilableCriteria;
|
import org.hibernate.jpa.criteria.compile.CompilableCriteria;
|
||||||
import org.hibernate.jpa.criteria.compile.CriteriaInterpretation;
|
import org.hibernate.jpa.criteria.compile.CriteriaInterpretation;
|
||||||
|
@ -76,9 +79,7 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
this.queryStructure = new QueryStructure<T>( this, criteriaBuilder );
|
this.queryStructure = new QueryStructure<T>( this, criteriaBuilder );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Class<T> getResultType() {
|
public Class<T> getResultType() {
|
||||||
return returnType;
|
return returnType;
|
||||||
}
|
}
|
||||||
|
@ -86,24 +87,18 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
|
|
||||||
// SELECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// SELECTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> distinct(boolean applyDistinction) {
|
public CriteriaQuery<T> distinct(boolean applyDistinction) {
|
||||||
queryStructure.setDistinct( applyDistinction );
|
queryStructure.setDistinct( applyDistinction );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public boolean isDistinct() {
|
public boolean isDistinct() {
|
||||||
return queryStructure.isDistinct();
|
return queryStructure.isDistinct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({ "unchecked" })
|
@SuppressWarnings({ "unchecked" })
|
||||||
public Selection<T> getSelection() {
|
public Selection<T> getSelection() {
|
||||||
return ( Selection<T> ) queryStructure.getSelection();
|
return ( Selection<T> ) queryStructure.getSelection();
|
||||||
|
@ -113,29 +108,25 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
queryStructure.setSelection( selection );
|
queryStructure.setSelection( selection );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> select(Selection<? extends T> selection) {
|
public CriteriaQuery<T> select(Selection<? extends T> selection) {
|
||||||
applySelection( selection );
|
applySelection( selection );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({ "unchecked" })
|
@SuppressWarnings({ "unchecked" })
|
||||||
public CriteriaQuery<T> multiselect(Selection<?>... selections) {
|
public CriteriaQuery<T> multiselect(Selection<?>... selections) {
|
||||||
return multiselect( Arrays.asList( selections ) );
|
return multiselect( Arrays.asList( selections ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({ "unchecked" })
|
@SuppressWarnings({ "unchecked" })
|
||||||
public CriteriaQuery<T> multiselect(List<Selection<?>> selections) {
|
public CriteriaQuery<T> multiselect(List<Selection<?>> selections) {
|
||||||
final Selection<? extends T> selection;
|
final Selection<? extends T> selection;
|
||||||
|
|
||||||
|
validateSelections( selections );
|
||||||
|
|
||||||
if ( Tuple.class.isAssignableFrom( getResultType() ) ) {
|
if ( Tuple.class.isAssignableFrom( getResultType() ) ) {
|
||||||
selection = ( Selection<? extends T> ) criteriaBuilder().tuple( selections );
|
selection = ( Selection<? extends T> ) criteriaBuilder().tuple( selections );
|
||||||
}
|
}
|
||||||
|
@ -168,26 +159,34 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateSelections(List<Selection<?>> selections) {
|
||||||
|
// handle the requirement that we validate that the incoming selections do not contain
|
||||||
|
// duplicate aliases.
|
||||||
|
final HashSet<String> aliases = new HashSet<String>( 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ROOTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Set<Root<?>> getRoots() {
|
public Set<Root<?>> getRoots() {
|
||||||
return queryStructure.getRoots();
|
return queryStructure.getRoots();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public <X> Root<X> from(EntityType<X> entityType) {
|
public <X> Root<X> from(EntityType<X> entityType) {
|
||||||
return queryStructure.from( entityType );
|
return queryStructure.from( entityType );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public <X> Root<X> from(Class<X> entityClass) {
|
public <X> Root<X> from(Class<X> entityClass) {
|
||||||
return queryStructure.from( entityClass );
|
return queryStructure.from( entityClass );
|
||||||
}
|
}
|
||||||
|
@ -195,24 +194,18 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
|
|
||||||
// RESTRICTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// RESTRICTION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Predicate getRestriction() {
|
public Predicate getRestriction() {
|
||||||
return queryStructure.getRestriction();
|
return queryStructure.getRestriction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> where(Expression<Boolean> expression) {
|
public CriteriaQuery<T> where(Expression<Boolean> expression) {
|
||||||
queryStructure.setRestriction( criteriaBuilder().wrap( expression ) );
|
queryStructure.setRestriction( criteriaBuilder().wrap( expression ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> where(Predicate... predicates) {
|
public CriteriaQuery<T> where(Predicate... predicates) {
|
||||||
// TODO : assuming this should be a conjuntion, but the spec does not say specifically...
|
// TODO : assuming this should be a conjuntion, but the spec does not say specifically...
|
||||||
queryStructure.setRestriction( criteriaBuilder().and( predicates ) );
|
queryStructure.setRestriction( criteriaBuilder().and( predicates ) );
|
||||||
|
@ -222,44 +215,35 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
|
|
||||||
// GROUPING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// GROUPING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public List<Expression<?>> getGroupList() {
|
public List<Expression<?>> getGroupList() {
|
||||||
return queryStructure.getGroupings();
|
return queryStructure.getGroupings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> groupBy(Expression<?>... groupings) {
|
public CriteriaQuery<T> groupBy(Expression<?>... groupings) {
|
||||||
queryStructure.setGroupings( groupings );
|
queryStructure.setGroupings( groupings );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public CriteriaQuery<T> groupBy(List<Expression<?>> groupings) {
|
public CriteriaQuery<T> groupBy(List<Expression<?>> groupings) {
|
||||||
queryStructure.setGroupings( groupings );
|
queryStructure.setGroupings( groupings );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Predicate getGroupRestriction() {
|
public Predicate getGroupRestriction() {
|
||||||
return queryStructure.getHaving();
|
return queryStructure.getHaving();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> having(Expression<Boolean> expression) {
|
public CriteriaQuery<T> having(Expression<Boolean> expression) {
|
||||||
queryStructure.setHaving( criteriaBuilder().wrap( expression ) );
|
queryStructure.setHaving( criteriaBuilder().wrap( expression ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> having(Predicate... predicates) {
|
public CriteriaQuery<T> having(Predicate... predicates) {
|
||||||
queryStructure.setHaving( criteriaBuilder().and( predicates ) );
|
queryStructure.setHaving( criteriaBuilder().and( predicates ) );
|
||||||
return this;
|
return this;
|
||||||
|
@ -268,16 +252,12 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
|
|
||||||
// ORDERING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ORDERING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public List<Order> getOrderList() {
|
public List<Order> getOrderList() {
|
||||||
return orderSpecs;
|
return orderSpecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> orderBy(Order... orders) {
|
public CriteriaQuery<T> orderBy(Order... orders) {
|
||||||
if ( orders != null && orders.length > 0 ) {
|
if ( orders != null && orders.length > 0 ) {
|
||||||
orderSpecs = Arrays.asList( orders );
|
orderSpecs = Arrays.asList( orders );
|
||||||
|
@ -288,28 +268,23 @@ public class CriteriaQueryImpl<T> extends AbstractNode implements CriteriaQuery<
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public CriteriaQuery<T> orderBy(List<Order> orders) {
|
public CriteriaQuery<T> orderBy(List<Order> orders) {
|
||||||
orderSpecs = orders;
|
orderSpecs = orders;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public Set<ParameterExpression<?>> getParameters() {
|
public Set<ParameterExpression<?>> getParameters() {
|
||||||
return queryStructure.getParameters();
|
return queryStructure.getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
public <U> Subquery<U> subquery(Class<U> subqueryType) {
|
public <U> Subquery<U> subquery(Class<U> subqueryType) {
|
||||||
return queryStructure.subquery( subqueryType );
|
return queryStructure.subquery( subqueryType );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void validate() {
|
public void validate() {
|
||||||
// getRoots() is explicitly supposed to return empty if none defined, no need to check for null
|
// getRoots() is explicitly supposed to return empty if none defined, no need to check for null
|
||||||
if ( getRoots().isEmpty() ) {
|
if ( getRoots().isEmpty() ) {
|
||||||
|
|
Loading…
Reference in New Issue