HHH-14452 Support set operations in JPA Criteria API

This commit is contained in:
Christian Beikov 2021-02-18 17:58:17 +01:00
parent 222837df95
commit 6b66feb0ac
46 changed files with 1011 additions and 475 deletions

View File

@ -646,7 +646,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
final QueryEngine queryEngine = getFactory().getQueryEngine();
final QueryInterpretationCache interpretationCache = queryEngine.getInterpretationCache();
final QuerySqmImpl query = new QuerySqmImpl(
final QuerySqmImpl<T> query = new QuerySqmImpl<>(
queryString,
interpretationCache.resolveHqlInterpretation(
queryString,
@ -940,7 +940,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
try {
return new QuerySqmImpl<>(
(SqmStatement) criteriaQuery,
(SqmStatement<T>) criteriaQuery,
criteriaQuery.getResultType(),
this
);
@ -955,7 +955,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
checkOpen();
try {
return new QuerySqmImpl<>(
(SqmUpdateStatement) criteriaUpdate,
(SqmUpdateStatement<?>) criteriaUpdate,
null,
this
);
@ -970,7 +970,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
checkOpen();
try {
return new QuerySqmImpl<>(
(SqmDeleteStatement) criteriaDelete,
(SqmDeleteStatement<?>) criteriaDelete,
null,
this
);

View File

@ -451,8 +451,9 @@ public class JpaMetamodelImpl implements JpaMetamodel {
// otherwise, try to handle it as a polymorphic reference
{
if ( polymorphicEntityReferenceMap.containsKey( javaType ) ) {
return (EntityDomainType<T>) polymorphicEntityReferenceMap.get( javaType );
EntityDomainType<T> polymorphicDomainType = (EntityDomainType<T>) polymorphicEntityReferenceMap.get( javaType );
if ( polymorphicDomainType != null ) {
return polymorphicDomainType;
}
final Set<EntityDomainType<?>> matchingDescriptors = new HashSet<>();
@ -464,11 +465,11 @@ public class JpaMetamodelImpl implements JpaMetamodel {
}
);
if ( !matchingDescriptors.isEmpty() ) {
final SqmPolymorphicRootDescriptor descriptor = new SqmPolymorphicRootDescriptor(
final SqmPolymorphicRootDescriptor<T> descriptor = new SqmPolymorphicRootDescriptor<>(
typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( javaType ),
matchingDescriptors
);
polymorphicEntityReferenceMap.put( javaType, descriptor );
polymorphicEntityReferenceMap.putIfAbsent( javaType, descriptor );
return descriptor;
}
}

View File

@ -18,6 +18,7 @@ import java.util.Set;
import javax.persistence.Tuple;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.ListJoin;
@ -33,6 +34,7 @@ import org.hibernate.NullPrecedence;
import org.hibernate.SortOrder;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.select.SqmSelectQuery;
/**
* Hibernate extensions to the JPA CriteriaBuilder.
@ -70,6 +72,38 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
<T> JpaCriteriaInsertSelect<T> createCriteriaInsertSelect(Class<T> targetEntity);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Set operation
default <T> JpaCriteriaQuery<T> unionAll(CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return union( true, query1, queries );
}
default <T> JpaCriteriaQuery<T> union(CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return union( false, query1, queries );
}
<T> JpaCriteriaQuery<T> union(boolean all, CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries);
default <T> JpaCriteriaQuery<T> intersectAll(CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return intersect( true, query1, queries );
}
default <T> JpaCriteriaQuery<T> intersect(CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return intersect( false, query1, queries );
}
<T> JpaCriteriaQuery<T> intersect(boolean all, CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries);
default <T> JpaCriteriaQuery<T> exceptAll(CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return except( true, query1, queries );
}
default <T> JpaCriteriaQuery<T> except(CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return except( false, query1, queries );
}
<T> JpaCriteriaQuery<T> except(boolean all, CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Paths

View File

@ -16,6 +16,8 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Selection;
import javax.persistence.metamodel.EntityType;
import org.hibernate.FetchClauseType;
/**
* Extension of the JPA {@link CriteriaQuery}
*
@ -23,13 +25,34 @@ import javax.persistence.metamodel.EntityType;
*/
public interface JpaCriteriaQuery<T> extends CriteriaQuery<T>, JpaQueryableCriteria<T>, JpaSelectCriteria<T> {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Limit/Offset/Fetch clause
JpaExpression<Number> getOffset();
JpaCriteriaQuery<T> offset(JpaExpression<? extends Number> offset);
JpaCriteriaQuery<T> offset(Number offset);
JpaExpression<Number> getFetch();
JpaCriteriaQuery<T> fetch(JpaExpression<? extends Number> fetch);
JpaCriteriaQuery<T> fetch(JpaExpression<? extends Number> fetch, FetchClauseType fetchClauseType);
JpaCriteriaQuery<T> fetch(Number fetch);
JpaCriteriaQuery<T> fetch(Number fetch, FetchClauseType fetchClauseType);
FetchClauseType getFetchClauseType();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Accessors
@Override
@SuppressWarnings("unchecked")
default List<Order> getOrderList() {
return (List) getQuerySpec().getSortSpecifications();
return (List) getQueryPart().getSortSpecifications();
}
/**

View File

@ -0,0 +1,38 @@
/*
* 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.query.criteria;
import java.util.List;
import org.hibernate.FetchClauseType;
import org.hibernate.SetOperator;
/**
* A query group i.e. query parts connected with a set operator.
*
* @author Christian Beikov
*/
public interface JpaQueryGroup<T> extends JpaQueryPart<T> {
List<? extends JpaQueryPart<T>> getQueryParts();
SetOperator getSetOperator();
void setSetOperator(SetOperator setOperator);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant overrides
JpaQueryGroup<T> setSortSpecifications(List<? extends JpaOrder> sortSpecifications);
JpaQueryGroup<T> setOffset(JpaExpression<?> offset);
JpaQueryGroup<T> setFetch(JpaExpression<?> fetch);
JpaQueryGroup<T> setFetch(JpaExpression<?> fetch, FetchClauseType fetchClauseType);
}

View File

@ -0,0 +1,45 @@
/*
* 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.query.criteria;
import java.util.List;
import org.hibernate.FetchClauseType;
/**
* Models a query part i.e. the commonalities between a query group and a query specification.
*
* @see JpaQueryStructure
* @see JpaQueryGroup
*
* @author Christian Beikov
*/
public interface JpaQueryPart<T> extends JpaCriteriaNode {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Ordering clause
List<? extends JpaOrder> getSortSpecifications();
JpaQueryPart<T> setSortSpecifications(List<? extends JpaOrder> sortSpecifications);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Limit/Offset/Fetch clause
<X> JpaExpression<X> getOffset();
JpaQueryPart<T> setOffset(JpaExpression<?> offset);
<X> JpaExpression<X> getFetch();
JpaQueryPart<T> setFetch(JpaExpression<?> fetch);
JpaQueryPart<T> setFetch(JpaExpression<?> fetch, FetchClauseType fetchClauseType);
FetchClauseType getFetchClauseType();
}

View File

@ -27,7 +27,7 @@ import org.hibernate.FetchClauseType;
*
* @author Steve Ebersole
*/
public interface JpaQueryStructure<T> extends JpaCriteriaNode {
public interface JpaQueryStructure<T> extends JpaQueryPart<T> {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Select clause
@ -78,27 +78,14 @@ public interface JpaQueryStructure<T> extends JpaCriteriaNode {
JpaQueryStructure<T> setGroupRestriction(Predicate... restrictions);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Ordering clause
List<? extends JpaOrder> getSortSpecifications();
// Covariant overrides
JpaQueryStructure<T> setSortSpecifications(List<? extends JpaOrder> sortSpecifications);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Limit/Offset/Fetch clause
<X> JpaExpression<X> getOffset();
JpaQueryStructure<T> setOffset(JpaExpression<?> offset);
<X> JpaExpression<X> getFetch();
JpaQueryStructure<T> setFetch(JpaExpression<?> fetch);
JpaQueryStructure<T> setFetch(JpaExpression<?> fetch, FetchClauseType fetchClauseType);
FetchClauseType getFetchClauseType();
}

View File

@ -23,6 +23,10 @@ public interface JpaSelectCriteria<T> extends AbstractQuery<T>, JpaCriteriaBase
* The query structure. See {@link JpaQueryStructure} for details
*/
JpaQueryStructure<T> getQuerySpec();
/**
* The query structure. See {@link JpaQueryStructure} for details
*/
JpaQueryPart<T> getQueryPart();
@Override
JpaSelectCriteria<T> distinct(boolean distinct);

View File

@ -28,7 +28,7 @@ public interface HqlTranslator {
*
* @return The semantic representation of the incoming query.
*/
SqmStatement translate(String hql);
<R> SqmStatement<R> translate(String hql);
/**
* Give the translator a chance to "shut down" if it needs to

View File

@ -43,6 +43,7 @@ import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmFromClause;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmBetweenPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmComparisonPredicate;
@ -72,6 +73,7 @@ import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.query.sqm.tree.update.SqmAssignment;
import org.hibernate.query.sqm.tree.update.SqmSetClause;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Handles splitting queries containing unmapped polymorphic references.
@ -79,25 +81,25 @@ import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
* @author Steve Ebersole
*/
public class QuerySplitter {
public static SqmSelectStatement[] split(
SqmSelectStatement statement,
public static <R> SqmSelectStatement<R>[] split(
SqmSelectStatement<R> statement,
SessionFactoryImplementor sessionFactory) {
// We only allow unmapped polymorphism in a very restricted way. Specifically,
// the unmapped polymorphic reference can only be a root and can be the only
// root. Use that restriction to locate the unmapped polymorphic reference
final SqmRoot unmappedPolymorphicReference = findUnmappedPolymorphicReference( statement );
final SqmRoot<?> unmappedPolymorphicReference = findUnmappedPolymorphicReference( statement.getQueryPart() );
if ( unmappedPolymorphicReference == null ) {
return new SqmSelectStatement[] { statement };
}
final SqmPolymorphicRootDescriptor<?> unmappedPolymorphicDescriptor = (SqmPolymorphicRootDescriptor) unmappedPolymorphicReference.getReferencedPathSource();
final SqmSelectStatement[] expanded = new SqmSelectStatement[ unmappedPolymorphicDescriptor.getImplementors().size() ];
final SqmPolymorphicRootDescriptor<?> unmappedPolymorphicDescriptor = (SqmPolymorphicRootDescriptor<?>) unmappedPolymorphicReference.getReferencedPathSource();
final SqmSelectStatement<R>[] expanded = new SqmSelectStatement[ unmappedPolymorphicDescriptor.getImplementors().size() ];
int i = -1;
for ( EntityDomainType<?> mappedDescriptor : unmappedPolymorphicDescriptor.getImplementors() ) {
i++;
final UnmappedPolymorphismReplacer replacer = new UnmappedPolymorphismReplacer(
final UnmappedPolymorphismReplacer<R> replacer = new UnmappedPolymorphismReplacer<>(
unmappedPolymorphicReference,
mappedDescriptor,
sessionFactory
@ -108,18 +110,26 @@ public class QuerySplitter {
return expanded;
}
private static SqmRoot findUnmappedPolymorphicReference(SqmSelectStatement statement) {
return statement.getQuerySpec()
.getFromClause()
.getRoots()
.stream()
.filter( sqmRoot -> sqmRoot.getReferencedPathSource() instanceof SqmPolymorphicRootDescriptor )
.findFirst()
.orElse( null );
private static SqmRoot<?> findUnmappedPolymorphicReference(SqmQueryPart<?> queryPart) {
if ( queryPart instanceof SqmQuerySpec<?> ) {
return ( (SqmQuerySpec<?>) queryPart ).getRoots()
.stream()
.filter( sqmRoot -> sqmRoot.getReferencedPathSource() instanceof SqmPolymorphicRootDescriptor )
.findFirst()
.orElse( null );
}
else {
final SqmQueryGroup<?> queryGroup = (SqmQueryGroup<?>) queryPart;
final SqmRoot<?> root = findUnmappedPolymorphicReference( queryGroup.getQueryParts().get( 0 ) );
if ( root != null ) {
throw new UnsupportedOperationException( "Polymorphic query group is unsupported!" );
}
return null;
}
}
@SuppressWarnings("unchecked")
private static class UnmappedPolymorphismReplacer extends BaseSemanticQueryWalker implements SqmCreationState {
private static class UnmappedPolymorphismReplacer<R> extends BaseSemanticQueryWalker implements SqmCreationState {
private final SqmRoot unmappedPolymorphicFromElement;
private final EntityDomainType mappedDescriptor;
private final SqmCreationContext creationContext;
@ -139,7 +149,12 @@ public class QuerySplitter {
}
@Override
public SqmUpdateStatement visitUpdateStatement(SqmUpdateStatement statement) {
public SqmInsertSelectStatement<R> visitInsertSelectStatement(SqmInsertSelectStatement<?> statement) {
throw new UnsupportedOperationException( "Not valid" );
}
@Override
public SqmUpdateStatement<R> visitUpdateStatement(SqmUpdateStatement<?> statement) {
throw new UnsupportedOperationException( "Not valid" );
}
@ -154,13 +169,13 @@ public class QuerySplitter {
}
@Override
public SqmDeleteStatement visitDeleteStatement(SqmDeleteStatement statement) {
public SqmDeleteStatement<R> visitDeleteStatement(SqmDeleteStatement<?> statement) {
throw new UnsupportedOperationException( "Not valid" );
}
@Override
public SqmSelectStatement visitSelectStatement(SqmSelectStatement statement) {
final SqmSelectStatement copy = new SqmSelectStatement( statement.nodeBuilder() );
public SqmSelectStatement<R> visitSelectStatement(SqmSelectStatement<?> statement) {
final SqmSelectStatement<R> copy = new SqmSelectStatement<>( statement.nodeBuilder() );
processingStateStack.push(
new SqmQuerySpecCreationProcessingStateStandardImpl(
@ -180,28 +195,28 @@ public class QuerySplitter {
}
@Override
public SqmQueryPart visitQueryPart(SqmQueryPart<?> queryPart) {
return (SqmQueryPart) super.visitQueryPart( queryPart );
public SqmQueryPart<R> visitQueryPart(SqmQueryPart<?> queryPart) {
return (SqmQueryPart<R>) super.visitQueryPart( queryPart );
}
@Override
public SqmQueryGroup visitQueryGroup(SqmQueryGroup<?> queryGroup) {
public SqmQueryGroup<R> visitQueryGroup(SqmQueryGroup<?> queryGroup) {
final List<? extends SqmQueryPart<?>> queryParts = queryGroup.getQueryParts();
final int size = queryParts.size();
final List<SqmQueryPart<?>> newQueryParts = new ArrayList<>( size );
final List<SqmQueryPart<R>> newQueryParts = new ArrayList<>( size );
for ( int i = 0; i < size; i++ ) {
newQueryParts.add( visitQueryPart( queryParts.get( i ) ) );
}
return new SqmQueryGroup( queryGroup.nodeBuilder(), queryGroup.getSetOperator(), newQueryParts );
return new SqmQueryGroup<>( queryGroup.nodeBuilder(), queryGroup.getSetOperator(), newQueryParts );
}
@Override
public SqmQuerySpec visitQuerySpec(SqmQuerySpec querySpec) {
public SqmQuerySpec<R> visitQuerySpec(SqmQuerySpec<?> querySpec) {
// NOTE : it is important that we visit the SqmFromClause first so that the
// fromElementCopyMap gets built before other parts of the queryspec
// are visited
final SqmQuerySpec sqmQuerySpec = new SqmQuerySpec( querySpec.nodeBuilder() );
final SqmQuerySpec<R> sqmQuerySpec = new SqmQuerySpec<>( querySpec.nodeBuilder() );
sqmQuerySpec.setFromClause( visitFromClause( querySpec.getFromClause() ) );
sqmQuerySpec.setSelectClause( visitSelectClause( querySpec.getSelectClause() ) );
sqmQuerySpec.setWhereClause( visitWhereClause( querySpec.getWhereClause() ) );
@ -210,12 +225,12 @@ public class QuerySplitter {
sqmQuerySpec.setOrderByClause( visitOrderByClause( querySpec.getOrderByClause() ) );
if ( querySpec.getFetchExpression() != null ) {
sqmQuerySpec.setFetchExpression(
(SqmExpression) querySpec.getFetchExpression().accept( this ),
(SqmExpression<?>) querySpec.getFetchExpression().accept( this ),
querySpec.getFetchClauseType()
);
}
if ( querySpec.getOffsetExpression() != null ) {
sqmQuerySpec.setOffsetExpression( (SqmExpression) querySpec.getOffsetExpression().accept( this ) );
sqmQuerySpec.setOffsetExpression( (SqmExpression<?>) querySpec.getOffsetExpression().accept( this ) );
}
return sqmQuerySpec;
@ -259,24 +274,24 @@ public class QuerySplitter {
}
@Override
public SqmRoot visitRootPath(SqmRoot sqmRoot) {
final SqmFrom sqmFrom = sqmFromCopyMap.get( sqmRoot );
public SqmRoot<?> visitRootPath(SqmRoot<?> sqmRoot) {
final SqmFrom<?, ?> sqmFrom = sqmFromCopyMap.get( sqmRoot );
if ( sqmFrom != null ) {
return (SqmRoot) sqmFrom;
return (SqmRoot<?>) sqmFrom;
}
final EntityDomainType pathSource;
final EntityDomainType<?> pathSource;
if ( sqmRoot == unmappedPolymorphicFromElement ) {
pathSource = mappedDescriptor;
}
else {
pathSource = sqmRoot.getReferencedPathSource();
}
final SqmRoot copy = new SqmRoot(
final SqmRoot<?> copy = new SqmRoot<>(
pathSource,
sqmRoot.getExplicitAlias(),
sqmRoot.nodeBuilder()
);
return (SqmRoot) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
return (SqmRoot<?>) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
copy.getNavigablePath(),
navigablePath -> {
sqmFromCopyMap.put( sqmRoot, copy );
@ -288,16 +303,16 @@ public class QuerySplitter {
}
@Override
public SqmCrossJoin visitCrossJoin(SqmCrossJoin join) {
final SqmFrom sqmFrom = sqmFromCopyMap.get( join );
public SqmCrossJoin<?> visitCrossJoin(SqmCrossJoin<?> join) {
final SqmFrom<?, ?> sqmFrom = sqmFromCopyMap.get( join );
if ( sqmFrom != null ) {
return (SqmCrossJoin) sqmFrom;
return (SqmCrossJoin<?>) sqmFrom;
}
return (SqmCrossJoin) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
return (SqmCrossJoin<?>) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
join.getNavigablePath(),
navigablePath -> {
final SqmRoot sqmRoot = (SqmRoot) sqmFromCopyMap.get( join.findRoot() );
final SqmCrossJoin copy = new SqmCrossJoin(
final SqmRoot<?> sqmRoot = (SqmRoot<?>) sqmFromCopyMap.get( join.findRoot() );
final SqmCrossJoin copy = new SqmCrossJoin<>(
join.getReferencedPathSource(),
join.getExplicitAlias(),
sqmRoot
@ -311,16 +326,16 @@ public class QuerySplitter {
}
@Override
public SqmEntityJoin visitQualifiedEntityJoin(SqmEntityJoin join) {
final SqmFrom sqmFrom = sqmFromCopyMap.get( join );
public SqmEntityJoin<?> visitQualifiedEntityJoin(SqmEntityJoin<?> join) {
final SqmFrom<?, ?> sqmFrom = sqmFromCopyMap.get( join );
if ( sqmFrom != null ) {
return (SqmEntityJoin) sqmFrom;
return (SqmEntityJoin<?>) sqmFrom;
}
return (SqmEntityJoin) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
return (SqmEntityJoin<?>) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
join.getNavigablePath(),
navigablePath -> {
final SqmRoot sqmRoot = (SqmRoot) sqmFromCopyMap.get( join.findRoot() );
final SqmEntityJoin copy = new SqmEntityJoin(
final SqmRoot<?> sqmRoot = (SqmRoot<?>) sqmFromCopyMap.get( join.findRoot() );
final SqmEntityJoin copy = new SqmEntityJoin<>(
join.getReferencedPathSource(),
join.getExplicitAlias(),
join.getSqmJoinType(),
@ -335,12 +350,12 @@ public class QuerySplitter {
}
@Override
public SqmAttributeJoin visitQualifiedAttributeJoin(SqmAttributeJoin join) {
SqmFrom sqmFrom = sqmFromCopyMap.get( join );
public SqmAttributeJoin<?, ?> visitQualifiedAttributeJoin(SqmAttributeJoin<?, ?> join) {
SqmFrom<?, ?> sqmFrom = sqmFromCopyMap.get( join );
if ( sqmFrom != null ) {
return (SqmAttributeJoin) sqmFrom;
return (SqmAttributeJoin<?, ?>) sqmFrom;
}
return (SqmAttributeJoin) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
return (SqmAttributeJoin<?, ?>) getProcessingStateStack().getCurrent().getPathRegistry().resolvePath(
join.getNavigablePath(),
navigablePath -> {
SqmAttributeJoin copy = join.makeCopy( getProcessingStateStack().getCurrent() );
@ -353,13 +368,13 @@ public class QuerySplitter {
}
@Override
public SqmBasicValuedSimplePath visitBasicValuedPath(SqmBasicValuedSimplePath path) {
public SqmBasicValuedSimplePath<?> visitBasicValuedPath(SqmBasicValuedSimplePath<?> path) {
final SqmPathRegistry pathRegistry = getProcessingStateStack().getCurrent().getPathRegistry();
return (SqmBasicValuedSimplePath) pathRegistry.resolvePath(
return (SqmBasicValuedSimplePath<?>) pathRegistry.resolvePath(
path.getNavigablePath(),
navigablePath -> {
final SqmBasicValuedSimplePath copy = new SqmBasicValuedSimplePath(
final SqmBasicValuedSimplePath<?> copy = new SqmBasicValuedSimplePath<>(
navigablePath,
path.getReferencedPathSource(),
pathRegistry.findFromByPath( path.getLhs().getNavigablePath() ),
@ -372,13 +387,13 @@ public class QuerySplitter {
}
@Override
public SqmEmbeddedValuedSimplePath visitEmbeddableValuedPath(SqmEmbeddedValuedSimplePath path) {
public SqmEmbeddedValuedSimplePath<?> visitEmbeddableValuedPath(SqmEmbeddedValuedSimplePath<?> path) {
final SqmPathRegistry pathRegistry = getProcessingStateStack().getCurrent().getPathRegistry();
return (SqmEmbeddedValuedSimplePath) pathRegistry.resolvePath(
return (SqmEmbeddedValuedSimplePath<?>) pathRegistry.resolvePath(
path.getNavigablePath(),
navigablePath -> {
final SqmEmbeddedValuedSimplePath copy = new SqmEmbeddedValuedSimplePath(
final SqmEmbeddedValuedSimplePath<?> copy = new SqmEmbeddedValuedSimplePath<>(
navigablePath,
path.getReferencedPathSource(),
pathRegistry.findFromByPath( path.getLhs().getNavigablePath() ),
@ -391,13 +406,13 @@ public class QuerySplitter {
}
@Override
public SqmEntityValuedSimplePath visitEntityValuedPath(SqmEntityValuedSimplePath path) {
public SqmEntityValuedSimplePath<?> visitEntityValuedPath(SqmEntityValuedSimplePath<?> path) {
final SqmPathRegistry pathRegistry = getProcessingStateStack().getCurrent().getPathRegistry();
return (SqmEntityValuedSimplePath) pathRegistry.resolvePath(
return (SqmEntityValuedSimplePath<?>) pathRegistry.resolvePath(
path.getNavigablePath(),
navigablePath -> {
final SqmEntityValuedSimplePath copy = new SqmEntityValuedSimplePath(
final SqmEntityValuedSimplePath<?> copy = new SqmEntityValuedSimplePath<>(
navigablePath,
path.getReferencedPathSource(),
pathRegistry.findFromByPath( path.getLhs().getNavigablePath() ),
@ -410,13 +425,13 @@ public class QuerySplitter {
}
@Override
public SqmPluralValuedSimplePath visitPluralValuedPath(SqmPluralValuedSimplePath path) {
public SqmPluralValuedSimplePath<?> visitPluralValuedPath(SqmPluralValuedSimplePath<?> path) {
final SqmPathRegistry pathRegistry = getProcessingStateStack().getCurrent().getPathRegistry();
return (SqmPluralValuedSimplePath) pathRegistry.resolvePath(
return (SqmPluralValuedSimplePath<?>) pathRegistry.resolvePath(
path.getNavigablePath(),
navigablePath -> {
final SqmPluralValuedSimplePath copy = new SqmPluralValuedSimplePath(
final SqmPluralValuedSimplePath<?> copy = new SqmPluralValuedSimplePath<>(
navigablePath,
path.getReferencedPathSource(),
pathRegistry.findFromByPath( path.getLhs().getNavigablePath() ),
@ -431,10 +446,10 @@ public class QuerySplitter {
@Override
public SqmSelectClause visitSelectClause(SqmSelectClause selectClause) {
SqmSelectClause copy = new SqmSelectClause( selectClause.isDistinct(), selectClause.nodeBuilder() );
for ( SqmSelection selection : selectClause.getSelections() ) {
for ( SqmSelection<?> selection : selectClause.getSelections() ) {
copy.addSelection(
new SqmSelection(
(SqmExpression) selection.getSelectableNode().accept( this ),
new SqmSelection<>(
(SqmExpression<?>) selection.getSelectableNode().accept( this ),
selection.getAlias(),
selectClause.nodeBuilder()
)
@ -444,21 +459,21 @@ public class QuerySplitter {
}
@Override
public SqmDynamicInstantiation visitDynamicInstantiation(SqmDynamicInstantiation original) {
final SqmDynamicInstantiationTarget instantiationTarget = original.getInstantiationTarget();
final SqmDynamicInstantiation copy;
public SqmDynamicInstantiation<?> visitDynamicInstantiation(SqmDynamicInstantiation<?> original) {
final SqmDynamicInstantiationTarget<?> instantiationTarget = original.getInstantiationTarget();
final SqmDynamicInstantiation<?> copy;
switch ( instantiationTarget.getNature() ) {
case MAP: {
copy = SqmDynamicInstantiation.forMapInstantiation(
instantiationTarget.getTargetTypeDescriptor(),
(JavaTypeDescriptor<Map<?, ?>>) instantiationTarget.getTargetTypeDescriptor(),
getCreationContext().getNodeBuilder()
);
break;
}
case LIST: {
copy = SqmDynamicInstantiation.forListInstantiation(
instantiationTarget.getTargetTypeDescriptor(),
(JavaTypeDescriptor<List<?>>) instantiationTarget.getTargetTypeDescriptor(),
getCreationContext().getNodeBuilder()
);
break;
@ -471,10 +486,10 @@ public class QuerySplitter {
}
}
for ( SqmDynamicInstantiationArgument originalArgument : ( (SqmDynamicInstantiation<?>) original ).getArguments() ) {
for ( SqmDynamicInstantiationArgument<?> originalArgument : original.getArguments() ) {
copy.addArgument(
new SqmDynamicInstantiationArgument(
( SqmSelectableNode) originalArgument.getSelectableNode().accept( this ),
new SqmDynamicInstantiationArgument<>(
( SqmSelectableNode<?>) originalArgument.getSelectableNode().accept( this ),
originalArgument.getAlias(),
getCreationContext().getNodeBuilder()
)

View File

@ -212,7 +212,7 @@ import static org.hibernate.type.spi.TypeConfiguration.isJdbcTemporalType;
*
* @author Steve Ebersole
*/
public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCreationState {
public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implements SqmCreationState {
private static final Logger log = Logger.getLogger( SemanticQueryBuilder.class );
@ -221,11 +221,11 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
* query.
*/
@SuppressWarnings("WeakerAccess")
public static SqmStatement buildSemanticModel(
public static <R> SqmStatement<R> buildSemanticModel(
HqlParser.StatementContext hqlParseTree,
SqmCreationOptions creationOptions,
SqmCreationContext creationContext) {
return new SemanticQueryBuilder( creationOptions, creationContext ).visitStatement( hqlParseTree );
return new SemanticQueryBuilder<R>( creationOptions, creationContext ).visitStatement( hqlParseTree );
}
private final SqmCreationOptions creationOptions;
@ -271,7 +271,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
// Grammar rules
@Override
public SqmStatement visitStatement(HqlParser.StatementContext ctx) {
public SqmStatement<R> visitStatement(HqlParser.StatementContext ctx) {
// parameters allow multi-valued bindings only in very limited cases, so for
// the base case here we say false
parameterDeclarationContextStack.push( () -> false );
@ -302,9 +302,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
// Top-level statements
@Override
public SqmSelectStatement visitSelectStatement(HqlParser.SelectStatementContext ctx) {
public SqmSelectStatement<R> visitSelectStatement(HqlParser.SelectStatementContext ctx) {
final HqlParser.QueryExpressionContext queryExpressionContext = ctx.queryExpression();
final SqmSelectStatement selectStatement = new SqmSelectStatement( creationContext.getNodeBuilder() );
final SqmSelectStatement<R> selectStatement = new SqmSelectStatement<>( creationContext.getNodeBuilder() );
parameterCollector = selectStatement;
@ -327,17 +327,16 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
public SqmInsertStatement visitInsertStatement(HqlParser.InsertStatementContext ctx) {
final SqmRoot<?> root = new SqmRoot<>(
visitEntityName( ctx.dmlTarget().entityName() ),
public SqmInsertStatement<R> visitInsertStatement(HqlParser.InsertStatementContext ctx) {
final SqmRoot<R> root = new SqmRoot<>(
(EntityDomainType<R>) visitEntityName( ctx.dmlTarget().entityName() ),
applyJpaCompliance( visitIdentificationVariableDef( ctx.dmlTarget().identificationVariableDef() ) ),
creationContext.getNodeBuilder()
);
final HqlParser.QueryExpressionContext queryExpressionContext = ctx.queryExpression();
if ( queryExpressionContext != null ) {
final SqmInsertSelectStatement<?> insertStatement = new SqmInsertSelectStatement<>( root, creationContext.getNodeBuilder() );
final SqmInsertSelectStatement<R> insertStatement = new SqmInsertSelectStatement<>( root, creationContext.getNodeBuilder() );
parameterCollector = insertStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(
insertStatement,
@ -358,7 +357,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
processingStateStack.push( stateFieldsProcessingState );
try {
for ( HqlParser.DotIdentifierSequenceContext stateFieldCtx : ctx.targetFieldsSpec().dotIdentifierSequence() ) {
final SqmPath stateField = (SqmPath) visitDotIdentifierSequence( stateFieldCtx );
final SqmPath<?> stateField = (SqmPath<?>) visitDotIdentifierSequence( stateFieldCtx );
// todo : validate each resolved stateField...
insertStatement.addInsertTargetStateField( stateField );
}
@ -375,7 +374,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
else {
final SqmInsertValuesStatement<?> insertStatement = new SqmInsertValuesStatement<>( root, creationContext.getNodeBuilder() );
final SqmInsertValuesStatement<R> insertStatement = new SqmInsertValuesStatement<>( root, creationContext.getNodeBuilder() );
parameterCollector = insertStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(
insertStatement,
@ -389,7 +388,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
for ( HqlParser.ValuesContext values : ctx.valuesList().values() ) {
SqmValues sqmValues = new SqmValues();
for ( HqlParser.ExpressionContext expressionContext : values.expression() ) {
sqmValues.getExpressions().add( (SqmExpression) expressionContext.accept( this ) );
sqmValues.getExpressions().add( (SqmExpression<?>) expressionContext.accept( this ) );
}
insertStatement.getValuesList().add( sqmValues );
}
@ -410,14 +409,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
public SqmUpdateStatement visitUpdateStatement(HqlParser.UpdateStatementContext ctx) {
final SqmRoot<?> root = new SqmRoot<>(
visitEntityName( ctx.dmlTarget().entityName() ),
public SqmUpdateStatement<R> visitUpdateStatement(HqlParser.UpdateStatementContext ctx) {
final SqmRoot<R> root = new SqmRoot<>(
(EntityDomainType<R>) visitEntityName( ctx.dmlTarget().entityName() ),
visitIdentificationVariableDef( ctx.dmlTarget().identificationVariableDef() ),
creationContext.getNodeBuilder()
);
final SqmUpdateStatement<?> updateStatement = new SqmUpdateStatement<>( root, creationContext.getNodeBuilder() );
final SqmUpdateStatement<R> updateStatement = new SqmUpdateStatement<>( root, creationContext.getNodeBuilder() );
parameterCollector = updateStatement;
final SqmDmlCreationProcessingState processingState = new SqmDmlCreationProcessingState(
updateStatement,
@ -430,7 +429,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
for ( HqlParser.AssignmentContext assignmentContext : ctx.setClause().assignment() ) {
updateStatement.applyAssignment(
consumeDomainPath( assignmentContext.dotIdentifierSequence() ),
(SqmExpression) assignmentContext.expression().accept( this )
(SqmExpression<?>) assignmentContext.expression().accept( this )
);
}
@ -444,14 +443,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
public SqmDeleteStatement visitDeleteStatement(HqlParser.DeleteStatementContext ctx) {
final SqmRoot<?> root = new SqmRoot<>(
visitEntityName( ctx.dmlTarget().entityName() ),
public SqmDeleteStatement<R> visitDeleteStatement(HqlParser.DeleteStatementContext ctx) {
final SqmRoot<R> root = new SqmRoot<>(
(EntityDomainType<R>) visitEntityName( ctx.dmlTarget().entityName() ),
visitIdentificationVariableDef( ctx.dmlTarget().identificationVariableDef() ),
creationContext.getNodeBuilder()
);
final SqmDeleteStatement<?> deleteStatement = new SqmDeleteStatement<>( root, SqmQuerySource.HQL, creationContext.getNodeBuilder() );
final SqmDeleteStatement<R> deleteStatement = new SqmDeleteStatement<>( root, SqmQuerySource.HQL, creationContext.getNodeBuilder() );
parameterCollector = deleteStatement;
@ -480,14 +479,15 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
// Query spec
@Override
public SqmQueryPart visitSimpleQueryGroup(HqlParser.SimpleQueryGroupContext ctx) {
return (SqmQueryPart) ctx.simpleQueryExpression().accept( this );
public SqmQueryPart<Object> visitSimpleQueryGroup(HqlParser.SimpleQueryGroupContext ctx) {
//noinspection unchecked
return (SqmQueryPart<Object>) ctx.simpleQueryExpression().accept( this );
}
@Override
public SqmQueryPart visitQuerySpecExpression(HqlParser.QuerySpecExpressionContext ctx) {
public SqmQueryPart<Object> visitQuerySpecExpression(HqlParser.QuerySpecExpressionContext ctx) {
final List<ParseTree> children = ctx.children;
final SqmQueryPart queryPart = visitQuerySpec( (HqlParser.QuerySpecContext) children.get( 0 ) );
final SqmQueryPart<Object> queryPart = visitQuerySpec( (HqlParser.QuerySpecContext) children.get( 0 ) );
if ( children.size() > 1 ) {
visitQueryOrder( queryPart, (HqlParser.QueryOrderContext) children.get( 1 ) );
}
@ -495,9 +495,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
public SqmQueryPart visitNestedQueryExpression(HqlParser.NestedQueryExpressionContext ctx) {
public SqmQueryPart<Object> visitNestedQueryExpression(HqlParser.NestedQueryExpressionContext ctx) {
final List<ParseTree> children = ctx.children;
final SqmQueryPart queryPart = (SqmQueryPart) children.get( 1 ).accept( this );
//noinspection unchecked
final SqmQueryPart<Object> queryPart = (SqmQueryPart<Object>) children.get( 1 ).accept( this );
if ( children.size() > 3 ) {
visitQueryOrder( queryPart, (HqlParser.QueryOrderContext) children.get( 3 ) );
}
@ -505,17 +506,18 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
public SqmQueryGroup<?> visitSetQueryGroup(HqlParser.SetQueryGroupContext ctx) {
public SqmQueryGroup<Object> visitSetQueryGroup(HqlParser.SetQueryGroupContext ctx) {
if ( creationOptions.useStrictJpaCompliance() ) {
throw new StrictJpaComplianceViolation(
StrictJpaComplianceViolation.Type.SET_OPERATIONS
);
}
final List<ParseTree> children = ctx.children;
final SqmQueryPart<?> firstQueryPart = (SqmQueryPart<?>) children.get( 0 ).accept( this );
SqmQueryGroup queryGroup;
//noinspection unchecked
final SqmQueryPart<Object> firstQueryPart = (SqmQueryPart<Object>) children.get( 0 ).accept( this );
SqmQueryGroup<Object> queryGroup;
if ( firstQueryPart instanceof SqmQueryGroup<?>) {
queryGroup = (SqmQueryGroup<?>) firstQueryPart;
queryGroup = (SqmQueryGroup<Object>) firstQueryPart;
}
else {
queryGroup = new SqmQueryGroup<>( firstQueryPart );
@ -529,15 +531,15 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SetOperator operator = visitSetOperator( (HqlParser.SetOperatorContext) children.get( i ) );
final HqlParser.SimpleQueryExpressionContext simpleQueryCtx =
(HqlParser.SimpleQueryExpressionContext) children.get( i + 1 );
final List<SqmQueryPart<?>> queryParts;
final List<SqmQueryPart<Object>> queryParts;
if ( queryGroup.getSetOperator() == null || queryGroup.getSetOperator() == operator ) {
queryGroup.setSetOperator( operator );
queryParts = queryGroup.getQueryParts();
queryParts = queryGroup.queryParts();
}
else {
queryParts = new ArrayList<>( size - ( i >> 1 ) );
queryParts.add( queryGroup );
queryGroup = new SqmQueryGroup(
queryGroup = new SqmQueryGroup<>(
creationContext.getNodeBuilder(),
operator,
queryParts
@ -545,7 +547,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
setCurrentQueryPart( queryGroup );
}
final SqmQueryPart<?> queryPart;
final SqmQueryPart<Object> queryPart;
try {
processingStateStack.push(
new SqmQuerySpecCreationProcessingStateStandardImpl(
@ -556,13 +558,13 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
);
final List<ParseTree> subChildren = simpleQueryCtx.children;
if ( subChildren.get( 0 ) instanceof HqlParser.QuerySpecContext ) {
final SqmQuerySpec<?> querySpec = new SqmQuerySpec<>( creationContext.getNodeBuilder() );
final SqmQuerySpec<Object> querySpec = new SqmQuerySpec<>( creationContext.getNodeBuilder() );
queryParts.add( querySpec );
queryPart = visitQuerySpecExpression( (HqlParser.QuerySpecExpressionContext) simpleQueryCtx );
}
else {
try {
final SqmSelectStatement selectStatement = new SqmSelectStatement( creationContext.getNodeBuilder() );
final SqmSelectStatement<Object> selectStatement = new SqmSelectStatement<>( creationContext.getNodeBuilder() );
processingStateStack.push(
new SqmQuerySpecCreationProcessingStateStandardImpl(
processingStateStack.getCurrent(),
@ -586,7 +588,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new SemanticException( "All query parts must have the same arity!" );
}
for ( int j = 0; j < firstSelectionSize; j++ ) {
final JavaTypeDescriptor firstJavaTypeDescriptor = firstSelections.get( j ).getNodeJavaTypeDescriptor();
final JavaTypeDescriptor<?> firstJavaTypeDescriptor = firstSelections.get( j ).getNodeJavaTypeDescriptor();
if ( firstJavaTypeDescriptor != selections.get( j ).getNodeJavaTypeDescriptor() ) {
throw new SemanticException(
"Select items of the same index must have the same java type across all query parts!"
@ -664,8 +666,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
public SqmQuerySpec<?> visitQuerySpec(HqlParser.QuerySpecContext ctx) {
final SqmQuerySpec<?> sqmQuerySpec = currentQuerySpec();
public SqmQuerySpec<Object> visitQuerySpec(HqlParser.QuerySpecContext ctx) {
//noinspection unchecked
final SqmQuerySpec<Object> sqmQuerySpec = (SqmQuerySpec<Object>) currentQuerySpec();
// visit from-clause first!!!
treatHandlerStack.push( new TreatHandlerFromClause() );
@ -2848,7 +2851,6 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
private <J> BasicDomainType<J> resolveExpressableTypeBasic(Class<J> javaType) {
//noinspection unchecked
return creationContext.getJpaMetamodel().getTypeConfiguration().standardBasicTypeForJavaType( javaType );
}

View File

@ -70,14 +70,14 @@ public class StandardHqlTranslator implements HqlTranslator {
}
@Override
public SqmStatement translate(String query) {
public <R> SqmStatement<R> translate(String query) {
HqlLogging.QUERY_LOGGER.debugf( "HQL : " + query );
final HqlParser.StatementContext hqlParseTree = parseHql( query );
// then we perform semantic analysis and build the semantic representation...
try {
final SqmStatement sqmStatement = SemanticQueryBuilder.buildSemanticModel(
final SqmStatement<R> sqmStatement = SemanticQueryBuilder.buildSemanticModel(
hqlParseTree,
sqmCreationOptions,
sqmCreationContext

View File

@ -21,5 +21,5 @@ public interface HqlQueryImplementor<R> extends QueryImplementor<R>, NameableQue
@Override
ParameterMetadataImplementor getParameterMetadata();
SqmStatement getSqmStatement();
SqmStatement<R> getSqmStatement();
}

View File

@ -132,7 +132,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
// NOTE : if we get here, a result-type of some kind (other than Object[].class) was specified
final List<SqmSelection> selections = sqm.getQuerySpec().getSelectClause().getSelections();
final List<SqmSelection> selections = sqm.getQueryPart().getFirstQuerySpec().getSelectClause().getSelections();
if ( Tuple.class.isAssignableFrom( resultType ) ) {
// resultType is Tuple..
if ( queryOptions.getTupleTransformer() == null ) {

View File

@ -17,14 +17,11 @@ import javax.persistence.Parameter;
import javax.persistence.PersistenceException;
import javax.persistence.Tuple;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.ScrollMode;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.engine.query.spi.EntityGraphQueryHint;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.RowSelection;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.graph.GraphSemantic;
@ -48,7 +45,6 @@ import org.hibernate.query.spi.HqlInterpretation;
import org.hibernate.query.spi.MutableQueryOptions;
import org.hibernate.query.spi.NonSelectQueryPlan;
import org.hibernate.query.spi.ParameterMetadataImplementor;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.QueryInterpretationCache;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings;
@ -66,6 +62,8 @@ import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
import org.hibernate.query.sqm.tree.select.SqmQueryGroup;
import org.hibernate.query.sqm.tree.select.SqmQueryPart;
import org.hibernate.query.sqm.tree.select.SqmQuerySpec;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.select.SqmSelection;
@ -90,8 +88,8 @@ public class QuerySqmImpl<R>
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( QuerySqmImpl.class );
private final String hqlString;
private final SqmStatement sqmStatement;
private final Class resultType;
private final SqmStatement<R> sqmStatement;
private final Class<R> resultType;
private final ParameterMetadataImplementor parameterMetadata;
private final DomainParameterXref domainParameterXref;
@ -168,7 +166,7 @@ public class QuerySqmImpl<R>
public QuerySqmImpl(
String hqlString,
HqlInterpretation hqlInterpretation,
Class resultType,
Class<R> resultType,
SharedSessionContractImplementor producer) {
super( producer );
@ -179,8 +177,11 @@ public class QuerySqmImpl<R>
if ( resultType != null ) {
SqmUtil.verifyIsSelectStatement( sqmStatement );
//noinspection unchecked
checkQueryReturnType( (SqmSelectStatement<R>) sqmStatement, resultType, producer.getFactory() );
visitQueryReturnType(
( (SqmSelectStatement<R>) sqmStatement ).getQueryPart(),
resultType,
producer.getFactory()
);
}
this.parameterMetadata = hqlInterpretation.getParameterMetadata();
@ -193,36 +194,17 @@ public class QuerySqmImpl<R>
* Form used for criteria queries
*/
public QuerySqmImpl(
SqmStatement sqmStatement,
Class resultType,
SqmStatement<R> sqmStatement,
Class<R> resultType,
SharedSessionContractImplementor producer) {
super( producer );
if ( sqmStatement instanceof SqmSelectStatement ) {
final SqmSelectStatement sqmSelectStatement = (SqmSelectStatement) sqmStatement;
final SqmQuerySpec sqmQuerySpec = sqmSelectStatement.getQuerySpec();
final List<SqmSelection> sqmSelections = sqmQuerySpec.getSelectClause().getSelections();
// make sure there is at least one root
final List<SqmRoot<?>> sqmRoots = sqmQuerySpec.getFromClause().getRoots();
if ( sqmRoots == null || sqmRoots.isEmpty() ) {
throw new IllegalArgumentException( "Criteria did not define any query roots" );
}
if ( sqmSelections == null || sqmSelections.isEmpty() ) {
// if there is a single root, use that as the selection
if ( sqmRoots.size() == 1 ) {
final SqmRoot<?> sqmRoot = sqmRoots.get( 0 );
sqmQuerySpec.getSelectClause().add( sqmRoot, null );
}
else {
throw new IllegalArgumentException( );
}
}
if ( resultType != null ) {
checkQueryReturnType( (SqmSelectStatement<R>) sqmStatement, resultType, producer.getFactory() );
}
visitQueryReturnType(
( (SqmSelectStatement<R>) sqmStatement ).getQueryPart(),
resultType,
producer.getFactory()
);
}
else {
assert sqmStatement instanceof SqmDmlStatement;
@ -255,13 +237,50 @@ public class QuerySqmImpl<R>
}
}
private static <T> void checkQueryReturnType(SqmSelectStatement<T> sqm, Class<T> resultClass, SessionFactoryImplementor sessionFactory) {
private void visitQueryReturnType(
SqmQueryPart<R> queryPart,
Class<R> resultType,
SessionFactoryImplementor factory) {
if ( queryPart instanceof SqmQuerySpec<?> ) {
final SqmQuerySpec<R> sqmQuerySpec = (SqmQuerySpec<R>) queryPart;
final List<SqmSelection> sqmSelections = sqmQuerySpec.getSelectClause().getSelections();
// make sure there is at least one root
final List<SqmRoot<?>> sqmRoots = sqmQuerySpec.getFromClause().getRoots();
if ( sqmRoots == null || sqmRoots.isEmpty() ) {
throw new IllegalArgumentException( "Criteria did not define any query roots" );
}
if ( sqmSelections == null || sqmSelections.isEmpty() ) {
// if there is a single root, use that as the selection
if ( sqmRoots.size() == 1 ) {
final SqmRoot<?> sqmRoot = sqmRoots.get( 0 );
sqmQuerySpec.getSelectClause().add( sqmRoot, null );
}
else {
throw new IllegalArgumentException( );
}
}
if ( resultType != null ) {
checkQueryReturnType( sqmQuerySpec, resultType, factory );
}
}
else {
final SqmQueryGroup<R> queryGroup = (SqmQueryGroup<R>) queryPart;
for ( SqmQueryPart<R> sqmQueryPart : queryGroup.getQueryParts() ) {
visitQueryReturnType( sqmQueryPart, resultType, factory );
}
}
}
private static <T> void checkQueryReturnType(SqmQuerySpec<T> querySpec, Class<T> resultClass, SessionFactoryImplementor sessionFactory) {
if ( resultClass == null ) {
// nothing to check
return;
}
final List<SqmSelection> selections = sqm.getQuerySpec().getSelectClause().getSelections();
final List<SqmSelection> selections = querySpec.getSelectClause().getSelections();
if ( resultClass.isArray() ) {
// todo (6.0) : implement
@ -356,7 +375,7 @@ public class QuerySqmImpl<R>
}
@Override
public SqmStatement getSqmStatement() {
public SqmStatement<R> getSqmStatement() {
return sqmStatement;
}
@ -465,13 +484,13 @@ public class QuerySqmImpl<R>
SqmUtil.verifyIsSelectStatement( getSqmStatement() );
getSession().prepareForQueryExecution( requiresTxn( getLockOptions().findGreatestLockMode() ) );
final SqmSelectStatement<?> selectStatement = (SqmSelectStatement<?>) getSqmStatement();
final boolean containsCollectionFetches = selectStatement.getQuerySpec().containsCollectionFetches();
final boolean containsCollectionFetches = selectStatement.containsCollectionFetches();
final boolean hasLimit = queryOptions.hasLimit();
final boolean needsDistincting = (
selectStatement.getQuerySpec().getSelectClause().isDistinct() ||
final boolean needsDistincting = containsCollectionFetches && (
selectStatement.usesDistinct() ||
queryOptions.getGraph() != null ||
hasLimit )
&& containsCollectionFetches;
hasLimit
);
ExecutionContext executionContextToUse;
if ( queryOptions.hasLimit() && containsCollectionFetches ) {
boolean fail = getSessionFactory().getSessionFactoryOptions().isFailOnPaginationOverCollectionFetchEnabled();
@ -548,8 +567,8 @@ public class QuerySqmImpl<R>
}
private SelectQueryPlan<R> buildSelectQueryPlan() {
final SqmSelectStatement[] concreteSqmStatements = QuerySplitter.split(
(SqmSelectStatement) getSqmStatement(),
final SqmSelectStatement<R>[] concreteSqmStatements = QuerySplitter.split(
(SqmSelectStatement<R>) getSqmStatement(),
getSessionFactory()
);
@ -566,8 +585,8 @@ public class QuerySqmImpl<R>
}
@SuppressWarnings("unchecked")
private SelectQueryPlan<R> buildAggregatedSelectQueryPlan(SqmSelectStatement[] concreteSqmStatements) {
final SelectQueryPlan[] aggregatedQueryPlans = new SelectQueryPlan[ concreteSqmStatements.length ];
private SelectQueryPlan<R> buildAggregatedSelectQueryPlan(SqmSelectStatement<R>[] concreteSqmStatements) {
final SelectQueryPlan<R>[] aggregatedQueryPlans = new SelectQueryPlan[ concreteSqmStatements.length ];
// todo (6.0) : we want to make sure that certain thing (ResultListTransformer, etc) only get applied at the aggregator-level
@ -583,7 +602,7 @@ public class QuerySqmImpl<R>
}
private SelectQueryPlan<R> buildConcreteSelectQueryPlan(
SqmSelectStatement concreteSqmStatement,
SqmSelectStatement<R> concreteSqmStatement,
Class<R> resultType,
QueryOptions queryOptions) {
return new ConcreteSqmSelectQueryPlan<>(
@ -633,15 +652,15 @@ public class QuerySqmImpl<R>
private NonSelectQueryPlan buildNonSelectQueryPlan() {
// to get here the SQM statement has already been validated to be
// a non-select variety...
if ( getSqmStatement() instanceof SqmDeleteStatement ) {
if ( getSqmStatement() instanceof SqmDeleteStatement<?> ) {
return buildDeleteQueryPlan();
}
if ( getSqmStatement() instanceof SqmUpdateStatement ) {
if ( getSqmStatement() instanceof SqmUpdateStatement<?> ) {
return buildUpdateQueryPlan();
}
if ( getSqmStatement() instanceof SqmInsertStatement ) {
if ( getSqmStatement() instanceof SqmInsertStatement<?> ) {
return buildInsertQueryPlan();
}
@ -649,7 +668,7 @@ public class QuerySqmImpl<R>
}
private NonSelectQueryPlan buildDeleteQueryPlan() {
final SqmDeleteStatement sqmDelete = (SqmDeleteStatement) getSqmStatement();
final SqmDeleteStatement<R> sqmDelete = (SqmDeleteStatement<R>) getSqmStatement();
final String entityNameToDelete = sqmDelete.getTarget().getReferencedPathSource().getHibernateEntityName();
final EntityPersister entityDescriptor = getSessionFactory().getDomainModel().findEntityDescriptor( entityNameToDelete );
@ -664,7 +683,7 @@ public class QuerySqmImpl<R>
}
private NonSelectQueryPlan buildUpdateQueryPlan() {
final SqmUpdateStatement sqmUpdate = (SqmUpdateStatement) getSqmStatement();
final SqmUpdateStatement<R> sqmUpdate = (SqmUpdateStatement<R>) getSqmStatement();
final String entityNameToUpdate = sqmUpdate.getTarget().getReferencedPathSource().getHibernateEntityName();
final EntityPersister entityDescriptor = getSessionFactory().getDomainModel().findEntityDescriptor( entityNameToUpdate );
@ -679,7 +698,7 @@ public class QuerySqmImpl<R>
}
private NonSelectQueryPlan buildInsertQueryPlan() {
final SqmInsertStatement sqmInsert = (SqmInsertStatement) getSqmStatement();
final SqmInsertStatement<R> sqmInsert = (SqmInsertStatement<R>) getSqmStatement();
// final String entityNameToUpdate = sqmInsert.getTarget().getReferencedPathSource().getHibernateEntityName();
// final EntityPersister entityDescriptor = getSessionFactory().getDomainModel().findEntityDescriptor( entityNameToUpdate );

View File

@ -13,6 +13,7 @@ import java.sql.Time;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -21,6 +22,7 @@ import java.util.Set;
import java.util.function.Supplier;
import javax.persistence.Tuple;
import javax.persistence.criteria.CollectionJoin;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.ListJoin;
@ -35,6 +37,7 @@ import javax.persistence.criteria.Subquery;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.NullPrecedence;
import org.hibernate.QueryException;
import org.hibernate.SetOperator;
import org.hibernate.SortOrder;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
@ -50,13 +53,17 @@ import org.hibernate.query.TrimSpec;
import org.hibernate.query.UnaryArithmeticOperator;
import org.hibernate.query.criteria.JpaCoalesce;
import org.hibernate.query.criteria.JpaCompoundSelection;
import org.hibernate.query.criteria.JpaCriteriaQuery;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaQueryGroup;
import org.hibernate.query.criteria.JpaQueryPart;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.criteria.LiteralHandlingMode;
import org.hibernate.query.criteria.ValueHandlingMode;
import org.hibernate.query.internal.QueryHelper;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SqmQuerySource;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.spi.SqmCreationContext;
@ -100,6 +107,9 @@ import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiationArgument;
import org.hibernate.query.sqm.tree.select.SqmJpaCompoundSelection;
import org.hibernate.query.sqm.tree.select.SqmQueryGroup;
import org.hibernate.query.sqm.tree.select.SqmQueryPart;
import org.hibernate.query.sqm.tree.select.SqmSelectQuery;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
@ -203,11 +213,46 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
}
@Override
public <X, T> SqmExpression<X> cast(JpaExpression<T> expression, Class<X> castTargetJavaType) {
final BasicDomainType type = getTypeConfiguration().standardBasicTypeForJavaType( castTargetJavaType );
//noinspection unchecked
public <T> JpaCriteriaQuery<T> union(boolean all, CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return setOperation( all ? SetOperator.UNION_ALL : SetOperator.UNION, query1, queries );
}
@Override
public <T> JpaCriteriaQuery<T> intersect(boolean all, CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return setOperation( all ? SetOperator.INTERSECT_ALL : SetOperator.INTERSECT, query1, queries );
}
@Override
public <T> JpaCriteriaQuery<T> except(boolean all, CriteriaQuery<? extends T> query1, CriteriaQuery<?>... queries) {
return setOperation( all ? SetOperator.EXCEPT_ALL : SetOperator.EXCEPT, query1, queries );
}
private <T> JpaCriteriaQuery<T> setOperation(
SetOperator operator,
CriteriaQuery<? extends T> query1,
CriteriaQuery<?>... queries) {
final Class<T> resultType = (Class<T>) query1.getResultType();
final List<SqmQueryPart<T>> queryParts = new ArrayList<>( queries.length + 1 );
queryParts.add( ( (SqmSelectQuery<T>) query1 ).getQueryPart() );
for ( CriteriaQuery<?> query : queries ) {
if ( query.getResultType() != resultType ) {
throw new IllegalArgumentException( "Result type of all operands must match!" );
}
queryParts.add( ( (SqmSelectQuery<T>) query ).getQueryPart() );
}
return new SqmSelectStatement<>(
new SqmQueryGroup<>( this, operator, queryParts ),
resultType,
SqmQuerySource.CRITERIA,
this
);
}
@Override
public <X, T> SqmExpression<X> cast(JpaExpression<T> expression, Class<X> castTargetJavaType) {
final BasicDomainType<X> type = getTypeConfiguration().standardBasicTypeForJavaType( castTargetJavaType );
return getFunctionDescriptor("cast").generateSqmExpression(
asList( (SqmTypedNode) expression, new SqmCastTarget<>( type, this ) ),
asList( (SqmTypedNode<?>) expression, new SqmCastTarget<>( type, this ) ),
type,
queryEngine,
getJpaMetamodel().getTypeConfiguration()
@ -318,22 +363,23 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <Y> JpaCompoundSelection<Y> construct(Class<Y> resultClass, List<? extends JpaSelection<?>> arguments) {
final SqmDynamicInstantiation instantiation;
final SqmDynamicInstantiation<Y> instantiation;
if ( List.class.equals( resultClass ) ) {
instantiation = SqmDynamicInstantiation.forListInstantiation( this );
//noinspection unchecked
instantiation = (SqmDynamicInstantiation<Y>) SqmDynamicInstantiation.forListInstantiation( this );
}
else if ( Map.class.equals( resultClass ) ) {
instantiation = SqmDynamicInstantiation.forMapInstantiation( this );
//noinspection unchecked
instantiation = (SqmDynamicInstantiation<Y>) SqmDynamicInstantiation.forMapInstantiation( this );
}
else {
instantiation = SqmDynamicInstantiation.forClassInstantiation( resultClass, this );
}
for ( Selection<?> argument : arguments ) {
//noinspection unchecked
instantiation.addArgument(
new SqmDynamicInstantiationArgument(
(SqmSelectableNode) argument,
new SqmDynamicInstantiationArgument<>(
(SqmSelectableNode<?>) argument,
argument.getAlias(),
this
)
@ -348,33 +394,32 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public SqmSortSpecification sort(JpaExpression<?> sortExpression, SortOrder sortOrder, NullPrecedence nullPrecedence) {
return new SqmSortSpecification( (SqmExpression) sortExpression, sortOrder, nullPrecedence );
return new SqmSortSpecification( (SqmExpression<?>) sortExpression, sortOrder, nullPrecedence );
}
@Override
public SqmSortSpecification sort(JpaExpression<?> sortExpression, SortOrder sortOrder) {
return new SqmSortSpecification( (SqmExpression) sortExpression, sortOrder );
return new SqmSortSpecification( (SqmExpression<?>) sortExpression, sortOrder );
}
@Override
public SqmSortSpecification sort(JpaExpression<?> sortExpression) {
return new SqmSortSpecification( (SqmExpression) sortExpression );
return new SqmSortSpecification( (SqmExpression<?>) sortExpression );
}
@Override
public SqmSortSpecification asc(Expression<?> x) {
return new SqmSortSpecification( (SqmExpression) x, SortOrder.ASCENDING );
return new SqmSortSpecification( (SqmExpression<?>) x, SortOrder.ASCENDING );
}
@Override
public SqmSortSpecification desc(Expression<?> x) {
return new SqmSortSpecification( (SqmExpression) x, SortOrder.DESCENDING );
return new SqmSortSpecification( (SqmExpression<?>) x, SortOrder.DESCENDING );
}
@Override
public JpaCompoundSelection<Tuple> tuple(Selection<?>[] selections) {
//noinspection unchecked
return new SqmJpaCompoundSelection(
return new SqmJpaCompoundSelection<>(
ArrayHelper.toList( selections ),
getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Tuple.class ),
this
@ -384,8 +429,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public JpaCompoundSelection<Tuple> tuple(List<? extends JpaSelection<?>> selections) {
//noinspection unchecked
return new SqmJpaCompoundSelection(
selections,
return new SqmJpaCompoundSelection<>(
(List<SqmSelectableNode<?>>) selections,
getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Tuple.class ),
this
);
@ -395,7 +440,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public <R> SqmTuple<R> tuple(Class<R> tupleType, JpaExpression<?>... expressions) {
//noinspection unchecked
return new SqmTuple<>(
(List) asList( expressions ),
(List<SqmExpression<?>>) (List<?>) asList( expressions ),
// getTypeConfiguration().standardExpressableTypeForJavaType( tupleType ),
this
);
@ -405,7 +450,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public <R> SqmTuple<R> tuple(Class<R> tupleType, List<JpaExpression<?>> expressions) {
//noinspection unchecked
return new SqmTuple<>(
(List) expressions,
(List<SqmExpression<?>>) (List<?>) expressions,
// getTypeConfiguration().standardExpressableTypeForJavaType( tupleType ),
this
);
@ -415,18 +460,17 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public <R> SqmTuple<R> tuple(DomainType<R> tupleType, JpaExpression<?>... expressions) {
//noinspection unchecked
return new SqmTuple<>(
(List) asList( expressions ),
(List<SqmExpression<?>>) (List<?>) asList( expressions ),
tupleType,
this
);
}
@Override
public <R> SqmTuple<R> tuple(
DomainType<R> tupleType, List<JpaExpression<?>> expressions) {
public <R> SqmTuple<R> tuple(DomainType<R> tupleType, List<JpaExpression<?>> expressions) {
//noinspection unchecked
return new SqmTuple<>(
new ArrayList<>((List) expressions),
new ArrayList<>( (List<SqmExpression<?>>) (List<?>) expressions ),
tupleType,
this
);
@ -434,8 +478,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public JpaCompoundSelection<Object[]> array(Selection<?>[] selections) {
//noinspection unchecked
return new SqmJpaCompoundSelection(
return new SqmJpaCompoundSelection<>(
ArrayHelper.toList( selections ),
getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Object[].class ),
this
@ -445,8 +488,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public JpaCompoundSelection<Object[]> array(List<? extends JpaSelection<?>> selections) {
//noinspection unchecked
return new SqmJpaCompoundSelection(
selections,
return new SqmJpaCompoundSelection<>(
(List<SqmSelectableNode<?>>) selections,
getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Object[].class ),
this
);
@ -455,7 +498,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <N extends Number> SqmExpression<Double> avg(Expression<N> argument) {
return getFunctionDescriptor("avg").generateSqmExpression(
(SqmTypedNode) argument,
(SqmTypedNode<?>) argument,
StandardBasicTypes.DOUBLE,
queryEngine,
getJpaMetamodel().getTypeConfiguration()
@ -465,7 +508,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <N extends Number> SqmExpression<N> sum(Expression<N> argument) {
return getFunctionDescriptor("sum").generateSqmExpression(
(SqmTypedNode) argument,
(SqmTypedNode<?>) argument,
(AllowableFunctionReturnType<N>) ( (SqmExpression<N>) argument ).getNodeType(),
queryEngine,
getJpaMetamodel().getTypeConfiguration()
@ -484,9 +527,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <N extends Number> SqmExpression<N> max(Expression<N> argument) {
//noinspection unchecked
return getFunctionDescriptor("max").generateSqmExpression(
(SqmTypedNode) argument,
(SqmTypedNode<?>) argument,
(AllowableFunctionReturnType<N>) ((SqmExpression<N>) argument).getNodeType(),
queryEngine,
getJpaMetamodel().getTypeConfiguration()
@ -495,9 +537,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <N extends Number> SqmExpression<N> min(Expression<N> argument) {
//noinspection unchecked
return getFunctionDescriptor("min").generateSqmExpression(
(SqmTypedNode) argument,
(SqmTypedNode<?>) argument,
(AllowableFunctionReturnType<N>) ((SqmExpression<N>) argument).getNodeType(),
queryEngine,
getJpaMetamodel().getTypeConfiguration()
@ -516,9 +557,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public SqmExpression<Long> count(Expression<?> argument) {
//noinspection unchecked
return getFunctionDescriptor("count").generateSqmExpression(
(SqmTypedNode) argument,
(SqmTypedNode<?>) argument,
StandardBasicTypes.LONG,
queryEngine,
getJpaMetamodel().getTypeConfiguration()
@ -546,9 +586,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <N extends Number> SqmExpression<N> abs(Expression<N> x) {
//noinspection unchecked
return getFunctionDescriptor("abs").generateSqmExpression(
(SqmTypedNode) x,
(SqmTypedNode<?>) x,
(AllowableFunctionReturnType<N>) ((SqmExpression<N>) x).getNodeType(),
queryEngine,
getJpaMetamodel().getTypeConfiguration()
@ -557,19 +596,19 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <N extends Number> SqmExpression<N> sum(Expression<? extends N> x, Expression<? extends N> y) {
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, (SqmExpression) x, (SqmExpression) y );
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, (SqmExpression<?>) x, (SqmExpression<?>) y );
}
private <N extends Number> SqmExpression<N> createSqmArithmeticNode(
BinaryArithmeticOperator operator,
SqmExpression leftHandExpression,
SqmExpression rightHandExpression) {
SqmExpression<?> leftHandExpression,
SqmExpression<?> rightHandExpression) {
//noinspection unchecked
return new SqmBinaryArithmetic(
return new SqmBinaryArithmetic<>(
operator,
leftHandExpression,
rightHandExpression,
getDomainModel().getTypeConfiguration().resolveArithmeticType(
(SqmExpressable<N>) getDomainModel().getTypeConfiguration().resolveArithmeticType(
leftHandExpression.getNodeType(),
rightHandExpression.getNodeType(),
operator
@ -580,17 +619,17 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <N extends Number> SqmExpression<N> sum(Expression<? extends N> x, N y) {
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, (SqmExpression) x, value( y ) );
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, (SqmExpression<?>) x, value( y ) );
}
@Override
public <N extends Number> SqmExpression<N> sum(N x, Expression<? extends N> y) {
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, value( x ), (SqmExpression) y );
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, value( x ), (SqmExpression<?>) y );
}
@Override
public <N extends Number> SqmExpression<N> prod(Expression<? extends N> x, Expression<? extends N> y) {
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, value( x ), (SqmExpression) y );
return createSqmArithmeticNode( BinaryArithmeticOperator.ADD, value( x ), (SqmExpression<?>) y );
}
@Override
@ -607,8 +646,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public <N extends Number> SqmExpression<N> diff(Expression<? extends N> x, Expression<? extends N> y) {
return createSqmArithmeticNode(
BinaryArithmeticOperator.SUBTRACT,
(SqmExpression) x,
(SqmExpression) y
(SqmExpression<?>) x,
(SqmExpression<?>) y
);
}
@ -616,7 +655,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public <N extends Number> SqmExpression<N> diff(Expression<? extends N> x, N y) {
return createSqmArithmeticNode(
BinaryArithmeticOperator.SUBTRACT,
(SqmExpression) x,
(SqmExpression<?>) x,
value( y )
);
}
@ -626,7 +665,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
return createSqmArithmeticNode(
BinaryArithmeticOperator.SUBTRACT,
value( x ),
(SqmExpression) y
(SqmExpression<?>) y
);
}
@ -634,8 +673,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public SqmExpression<Number> quot(Expression<? extends Number> x, Expression<? extends Number> y) {
return createSqmArithmeticNode(
BinaryArithmeticOperator.QUOT,
(SqmExpression) x,
(SqmExpression) y
(SqmExpression<?>) x,
(SqmExpression<?>) y
);
}
@ -643,7 +682,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public SqmExpression<Number> quot(Expression<? extends Number> x, Number y) {
return createSqmArithmeticNode(
BinaryArithmeticOperator.QUOT,
(SqmExpression) x,
(SqmExpression<?>) x,
value( y )
);
}
@ -653,7 +692,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
return createSqmArithmeticNode(
BinaryArithmeticOperator.QUOT,
value( x ),
(SqmExpression) y
(SqmExpression<?>) y
);
}
@ -661,8 +700,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public SqmExpression<Integer> mod(Expression<Integer> x, Expression<Integer> y) {
return createSqmArithmeticNode(
BinaryArithmeticOperator.MODULO,
(SqmExpression) x,
(SqmExpression) y
(SqmExpression<?>) x,
(SqmExpression<?>) y
);
}
@ -670,7 +709,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public SqmExpression<Integer> mod(Expression<Integer> x, Integer y) {
return createSqmArithmeticNode(
BinaryArithmeticOperator.MODULO,
(SqmExpression) x,
(SqmExpression<?>) x,
value( y )
);
}
@ -680,7 +719,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
return createSqmArithmeticNode(
BinaryArithmeticOperator.MODULO,
value( x ),
(SqmExpression) y
(SqmExpression<?>) y
);
}
@ -688,9 +727,9 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
public SqmExpression<Double> sqrt(Expression<? extends Number> x) {
//noinspection unchecked
return getFunctionDescriptor("sqrt").generateSqmExpression(
(SqmTypedNode) x,
(AllowableFunctionReturnType) QueryHelper.highestPrecedenceType2(
((SqmExpression) x).getNodeType(),
(SqmTypedNode<?>) x,
(AllowableFunctionReturnType<Double>) QueryHelper.highestPrecedenceType2(
((SqmExpression<?>) x).getNodeType(),
StandardBasicTypes.DOUBLE
),
queryEngine,
@ -701,55 +740,55 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
@SuppressWarnings("unchecked")
public SqmExpression<Long> toLong(Expression<? extends Number> number) {
return ( (SqmExpression) number ).asLong();
return ( (SqmExpression<?>) number ).asLong();
}
@Override
@SuppressWarnings("unchecked")
public SqmExpression<Integer> toInteger(Expression<? extends Number> number) {
return ( (SqmExpression) number ).asInteger();
return ( (SqmExpression<?>) number ).asInteger();
}
@Override
@SuppressWarnings("unchecked")
public SqmExpression<Float> toFloat(Expression<? extends Number> number) {
return ( (SqmExpression) number ).asFloat();
return ( (SqmExpression<?>) number ).asFloat();
}
@Override
@SuppressWarnings("unchecked")
public SqmExpression<Double> toDouble(Expression<? extends Number> number) {
return ( (SqmExpression) number ).asDouble();
return ( (SqmExpression<?>) number ).asDouble();
}
@Override
@SuppressWarnings("unchecked")
public SqmExpression<BigDecimal> toBigDecimal(Expression<? extends Number> number) {
return ( (SqmExpression) number ).asBigDecimal();
return ( (SqmExpression<?>) number ).asBigDecimal();
}
@Override
@SuppressWarnings("unchecked")
public SqmExpression<BigInteger> toBigInteger(Expression<? extends Number> number) {
return ( (SqmExpression) number ).asBigInteger();
return ( (SqmExpression<?>) number ).asBigInteger();
}
@Override
@SuppressWarnings("unchecked")
public SqmExpression<String> toString(Expression<Character> character) {
return ( (SqmExpression) character ).asString();
return ( (SqmExpression<?>) character ).asString();
}
@Override
@SuppressWarnings("unchecked")
public <T> SqmLiteral<T> literal(T value) {
if ( value == null ) {
return (SqmLiteral<T>) new SqmLiteralNull( this );
return new SqmLiteralNull<>( this );
}
return new SqmLiteral(
//noinspection unchecked
return new SqmLiteral<>(
value,
getTypeConfiguration().standardBasicTypeForJavaType( value.getClass() ),
getTypeConfiguration().standardBasicTypeForJavaType( (Class<T>) value.getClass() ),
this
);
}
@ -782,8 +821,7 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext {
@Override
public <T> SqmExpression<T> nullLiteral(Class<T> resultClass) {
//noinspection unchecked
return new SqmLiteralNull( getTypeConfiguration().standardBasicTypeForJavaType( resultClass ), this );
return new SqmLiteralNull<>( getTypeConfiguration().standardBasicTypeForJavaType( resultClass ), this );
}
class MultiValueParameterType<T> implements AllowableParameterType<T> {

View File

@ -122,12 +122,14 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitSelectStatement(SqmSelectStatement<?> statement) {
visitCteContainer( statement );
visitQueryPart( statement.getQueryPart() );
return statement;
}
@Override
public Object visitUpdateStatement(SqmUpdateStatement<?> statement) {
visitCteContainer( statement );
visitRootPath( statement.getTarget() );
visitSetClause( statement.getSetClause() );
visitWhereClause( statement.getWhereClause() );
@ -151,6 +153,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitInsertSelectStatement(SqmInsertSelectStatement<?> statement) {
visitCteContainer( statement );
visitRootPath( statement.getTarget() );
for ( SqmPath<?> stateField : statement.getInsertionTargetPaths() ) {
stateField.accept( this );
@ -161,6 +164,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitInsertValuesStatement(SqmInsertValuesStatement<?> statement) {
visitCteContainer( statement );
visitRootPath( statement.getTarget() );
for ( SqmPath<?> stateField : statement.getInsertionTargetPaths() ) {
stateField.accept( this );
@ -173,6 +177,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitDeleteStatement(SqmDeleteStatement<?> statement) {
visitCteContainer( statement );
visitRootPath( statement.getTarget() );
visitWhereClause( statement.getWhereClause() );
return statement;
@ -200,8 +205,11 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitQueryGroup(SqmQueryGroup<?> queryGroup) {
for ( SqmQueryPart<?> queryPart : queryGroup.getQueryParts() ) {
visitQueryPart( queryPart );
queryPart.accept( this );
}
visitOrderByClause( queryGroup.getOrderByClause() );
visitOffsetExpression( queryGroup.getOffsetExpression() );
visitFetchExpression( queryGroup.getFetchExpression() );
return queryGroup;
}
@ -210,6 +218,8 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
visitFromClause( querySpec.getFromClause() );
visitSelectClause( querySpec.getSelectClause() );
visitWhereClause( querySpec.getWhereClause() );
visitGroupByClause( querySpec.getGroupByClauseExpressions() );
visitHavingClause( querySpec.getHavingClausePredicate() );
visitOrderByClause( querySpec.getOrderByClause() );
visitOffsetExpression( querySpec.getOffsetExpression() );
visitFetchExpression( querySpec.getFetchExpression() );
@ -228,7 +238,6 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
return sqmRoot;
}
@Override
public Object visitCrossJoin(SqmCrossJoin<?> joinedFromElement) {
joinedFromElement.visitSqmJoins( sqmJoin -> sqmJoin.accept( this ) );
@ -323,7 +332,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitValues(SqmValues values) {
for ( SqmExpression expression : values.getExpressions() ) {
for ( SqmExpression<?> expression : values.getExpressions() ) {
expression.accept( this );
}
return values;
@ -409,7 +418,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitInListPredicate(SqmInListPredicate<?> predicate) {
predicate.getTestExpression().accept( this );
for ( SqmExpression expression : predicate.getListExpressions() ) {
for ( SqmExpression<?> expression : predicate.getListExpressions() ) {
expression.accept( this );
}
return predicate;
@ -473,6 +482,9 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
@Override
public Object visitHavingClause(SqmPredicate sqmPredicate) {
if ( sqmPredicate == null ) {
return null;
}
return sqmPredicate.accept( this );
}

View File

@ -348,7 +348,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
if ( statement instanceof SqmSelectStatement<?> ) {
this.domainResults = new ArrayList<>(
( (SqmSelectStatement<?>) statement ).getQuerySpec()
( (SqmSelectStatement<?>) statement ).getQueryPart()
.getFirstQuerySpec()
.getSelectClause()
.getSelectionItems()
.size()
@ -507,6 +508,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public SqmTranslation<T> translate() {
final SqmStatement<?> sqmStatement = getStatement();
//noinspection unchecked
final T statement = (T) sqmStatement.accept( this );
return new StandardSqmTranslation<>(
statement,
@ -924,8 +926,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public Values visitValues(SqmValues sqmValues) {
Values values = new Values();
//noinspection rawtypes
for ( SqmExpression expression : sqmValues.getExpressions() ) {
for ( SqmExpression<?> expression : sqmValues.getExpressions() ) {
values.getExpressions().add( (Expression) expression.accept( this ) );
}
return values;

View File

@ -29,7 +29,6 @@ public class LiteralHelper {
LocalDateTime.from( JdbcTimestampTypeDescriptor.LITERAL_FORMATTER.parse( literalText ) )
);
//noinspection unchecked
return new SqmLiteral<>(
literal,
creationState.getCreationContext().getJpaMetamodel().getTypeConfiguration().standardBasicTypeForJavaType( Timestamp.class ),
@ -58,7 +57,6 @@ public class LiteralHelper {
final LocalDate localDate = LocalDate.from( JdbcDateTypeDescriptor.LITERAL_FORMATTER.parse( literalText ) );
final Date literal = new Date( localDate.toEpochDay() );
//noinspection unchecked
return new SqmLiteral<>(
literal,
creationState.getCreationContext().getJpaMetamodel().getTypeConfiguration().standardBasicTypeForJavaType( Date.class ),
@ -70,7 +68,6 @@ public class LiteralHelper {
final LocalTime localTime = LocalTime.from( JdbcTimeTypeDescriptor.LITERAL_FORMATTER.parse( literalText ) );
final Time literal = Time.valueOf( localTime );
//noinspection unchecked
return new SqmLiteral<>(
literal,
creationState.getCreationContext().getJpaMetamodel().getTypeConfiguration().standardBasicTypeForJavaType( Time.class ),

View File

@ -15,9 +15,9 @@ import java.util.List;
* @author Gavin King
*/
public class SqmValues {
private List<SqmExpression> expressions = new ArrayList<>();
private final List<SqmExpression<?>> expressions = new ArrayList<>();
public List<SqmExpression> getExpressions() {
public List<SqmExpression<?>> getExpressions() {
return expressions;
}
}

View File

@ -62,13 +62,13 @@ public abstract class AbstractJpaTupleElement<T>
protected final void setExpressableType(SqmExpressable<?> expressableType) {
//noinspection unchecked
this.expressableType = (SqmExpressable) expressableType;
this.expressableType = (SqmExpressable<T>) expressableType;
}
/**
* Protected access to set the JavaTypeDescriptor via Java Class
*/
protected void setJavaType(Class targetType) {
protected void setJavaType(Class<T> targetType) {
if ( targetType != null ) {
setExpressableType(
nodeBuilder().getDomainModel()

View File

@ -35,67 +35,65 @@ import static org.hibernate.query.DynamicInstantiationNature.MAP;
public class SqmDynamicInstantiation<T>
extends AbstractJpaSelection<T>
implements SqmSelectableNode<T>,
SqmAliasedExpressionContainer<SqmDynamicInstantiationArgument>,
SqmAliasedExpressionContainer<SqmDynamicInstantiationArgument<?>>,
JpaCompoundSelection<T>,
DomainResultProducer<T> {
private static final Logger log = Logger.getLogger( SqmDynamicInstantiation.class );
public static SqmDynamicInstantiation forClassInstantiation(
JavaTypeDescriptor targetJavaType,
public static <R> SqmDynamicInstantiation<R> forClassInstantiation(
JavaTypeDescriptor<R> targetJavaType,
NodeBuilder nodeBuilder) {
//noinspection unchecked
return new SqmDynamicInstantiation(
new DynamicInstantiationTargetImpl( CLASS, targetJavaType ),
return new SqmDynamicInstantiation<>(
new DynamicInstantiationTargetImpl<>( CLASS, targetJavaType ),
nodeBuilder
);
}
public static SqmDynamicInstantiation forClassInstantiation(
Class targetJavaType,
public static <R> SqmDynamicInstantiation<R> forClassInstantiation(
Class<R> targetJavaType,
NodeBuilder nodeBuilder) {
//noinspection unchecked
return forClassInstantiation(
nodeBuilder.getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( targetJavaType ),
nodeBuilder
);
}
public static SqmDynamicInstantiation forMapInstantiation(
JavaTypeDescriptor<Map> mapJavaTypeDescriptor,
public static <M extends Map<?, ?>> SqmDynamicInstantiation<M> forMapInstantiation(
JavaTypeDescriptor<M> mapJavaTypeDescriptor,
NodeBuilder nodeBuilder) {
//noinspection unchecked
return new SqmDynamicInstantiation(
new DynamicInstantiationTargetImpl( MAP, mapJavaTypeDescriptor ),
return new SqmDynamicInstantiation<>(
new DynamicInstantiationTargetImpl<>( MAP, mapJavaTypeDescriptor ),
nodeBuilder
);
}
public static SqmDynamicInstantiation forMapInstantiation(NodeBuilder nodeBuilder) {
return forMapInstantiation(
public static <M extends Map<?, ?>> SqmDynamicInstantiation<M> forMapInstantiation(NodeBuilder nodeBuilder) {
//noinspection unchecked
return (SqmDynamicInstantiation<M>) (SqmDynamicInstantiation<?>) forMapInstantiation(
nodeBuilder.getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Map.class ),
nodeBuilder
);
}
public static SqmDynamicInstantiation forListInstantiation(
JavaTypeDescriptor<List> listJavaTypeDescriptor,
public static <L extends List<?>> SqmDynamicInstantiation<L> forListInstantiation(
JavaTypeDescriptor<L> listJavaTypeDescriptor,
NodeBuilder nodeBuilder) {
//noinspection unchecked
return new SqmDynamicInstantiation(
new DynamicInstantiationTargetImpl( LIST, listJavaTypeDescriptor ),
return new SqmDynamicInstantiation<>(
new DynamicInstantiationTargetImpl<>( LIST, listJavaTypeDescriptor ),
nodeBuilder
);
}
public static SqmDynamicInstantiation forListInstantiation(NodeBuilder nodeBuilder) {
return forListInstantiation(
public static <L extends List<?>> SqmDynamicInstantiation<L> forListInstantiation(NodeBuilder nodeBuilder) {
//noinspection unchecked
return (SqmDynamicInstantiation<L>) (SqmDynamicInstantiation<?>) forListInstantiation(
nodeBuilder.getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( List.class ),
nodeBuilder
);
}
private final SqmDynamicInstantiationTarget <T>instantiationTarget;
private final SqmDynamicInstantiationTarget <T> instantiationTarget;
private List<SqmDynamicInstantiationArgument<?>> arguments;
private SqmDynamicInstantiation(
@ -123,7 +121,7 @@ public class SqmDynamicInstantiation<T>
return "<new " + instantiationTarget.getJavaType().getName() + ">";
}
public void addArgument(SqmDynamicInstantiationArgument argument) {
public void addArgument(SqmDynamicInstantiationArgument<?> argument) {
if ( instantiationTarget.getNature() == LIST ) {
// really should not have an alias...
if ( argument.getAlias() != null && log.isDebugEnabled() ) {
@ -153,8 +151,8 @@ public class SqmDynamicInstantiation<T>
}
@Override
public SqmDynamicInstantiationArgument add(SqmExpression<?> expression, String alias) {
final SqmDynamicInstantiationArgument argument = new SqmDynamicInstantiationArgument<>(
public SqmDynamicInstantiationArgument<?> add(SqmExpression<?> expression, String alias) {
final SqmDynamicInstantiationArgument<?> argument = new SqmDynamicInstantiationArgument<>(
expression,
alias,
nodeBuilder()
@ -164,7 +162,7 @@ public class SqmDynamicInstantiation<T>
}
@Override
public void add(SqmDynamicInstantiationArgument aliasExpression) {
public void add(SqmDynamicInstantiationArgument<?> aliasExpression) {
addArgument( aliasExpression );
}
@ -210,7 +208,7 @@ public class SqmDynamicInstantiation<T>
@Override
public void visitSubSelectableNodes(Consumer<SqmSelectableNode<?>> consumer) {
for ( SqmDynamicInstantiationArgument argument : arguments ) {
for ( SqmDynamicInstantiationArgument<?> argument : arguments ) {
consumer.accept( argument.getSelectableNode() );
}
}

View File

@ -6,10 +6,16 @@
*/
package org.hibernate.query.sqm.tree.select;
import java.util.Collections;
import java.util.List;
import org.hibernate.FetchClauseType;
import org.hibernate.SetOperator;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaOrder;
import org.hibernate.query.criteria.JpaQueryGroup;
import org.hibernate.query.criteria.JpaQueryPart;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
@ -18,7 +24,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
*
* @author Christian Beikov
*/
public class SqmQueryGroup<T> extends SqmQueryPart<T> {
public class SqmQueryGroup<T> extends SqmQueryPart<T> implements JpaQueryGroup<T> {
private final List<SqmQueryPart<T>> queryParts;
private SetOperator setOperator;
@ -36,6 +42,10 @@ public class SqmQueryGroup<T> extends SqmQueryPart<T> {
this.queryParts = queryParts;
}
public List<SqmQueryPart<T>> queryParts() {
return queryParts;
}
@Override
public SqmQuerySpec<T> getFirstQuerySpec() {
return queryParts.get( 0 ).getFirstQuerySpec();
@ -56,15 +66,41 @@ public class SqmQueryGroup<T> extends SqmQueryPart<T> {
return walker.visitQueryGroup( this );
}
@Override
public List<SqmQueryPart<T>> getQueryParts() {
return queryParts;
return Collections.unmodifiableList( queryParts );
}
@Override
public SetOperator getSetOperator() {
return setOperator;
}
@Override
public void setSetOperator(SetOperator setOperator) {
if ( setOperator == null ) {
throw new IllegalArgumentException();
}
this.setOperator = setOperator;
}
@Override
public SqmQueryGroup<T> setSortSpecifications(List<? extends JpaOrder> sortSpecifications) {
return (SqmQueryGroup<T>) super.setSortSpecifications( sortSpecifications );
}
@Override
public SqmQueryGroup<T> setOffset(JpaExpression<?> offset) {
return (SqmQueryGroup<T>) super.setOffset( offset );
}
@Override
public SqmQueryGroup<T> setFetch(JpaExpression<?> fetch) {
return (SqmQueryGroup<T>) super.setFetch( fetch );
}
@Override
public SqmQueryGroup<T> setFetch(JpaExpression<?> fetch, FetchClauseType fetchClauseType) {
return (SqmQueryGroup<T>) super.setFetch( fetch, fetchClauseType );
}
}

View File

@ -12,6 +12,7 @@ import java.util.List;
import org.hibernate.FetchClauseType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaOrder;
import org.hibernate.query.criteria.JpaQueryPart;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.tree.SqmVisitableNode;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
@ -22,7 +23,7 @@ import org.hibernate.type.StandardBasicTypes;
*
* @author Christian Beikov
*/
public abstract class SqmQueryPart<T> implements SqmVisitableNode {
public abstract class SqmQueryPart<T> implements SqmVisitableNode, JpaQueryPart<T> {
private final NodeBuilder nodeBuilder;
private SqmOrderByClause orderByClause;
@ -88,6 +89,7 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode {
}
}
@Override
public FetchClauseType getFetchClauseType() {
return fetchClauseType;
}
@ -95,6 +97,7 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA
@Override
public List<SqmSortSpecification> getSortSpecifications() {
if ( getOrderByClause() == null ) {
return Collections.emptyList();
@ -103,6 +106,7 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode {
return getOrderByClause().getSortSpecifications();
}
@Override
public SqmQueryPart<T> setSortSpecifications(List<? extends JpaOrder> sortSpecifications) {
if ( getOrderByClause() == null ) {
setOrderByClause( new SqmOrderByClause() );
@ -115,22 +119,32 @@ public abstract class SqmQueryPart<T> implements SqmVisitableNode {
}
@SuppressWarnings("unchecked")
@Override
public SqmExpression<?> getOffset() {
return getOffsetExpression();
}
@Override
public SqmQueryPart<T> setOffset(JpaExpression<?> offset) {
setOffsetExpression( (SqmExpression<?>) offset );
return this;
}
@SuppressWarnings("unchecked")
@Override
public SqmExpression<?> getFetch() {
return getFetchExpression();
}
@Override
public SqmQueryPart<T> setFetch(JpaExpression<?> fetch) {
setFetchExpression( (SqmExpression<?>) fetch );
return this;
}
@Override
public JpaQueryPart<T> setFetch(JpaExpression<?> fetch, FetchClauseType fetchClauseType) {
setFetchExpression( (SqmExpression<?>) fetch, fetchClauseType );
return this;
}
}

View File

@ -21,8 +21,10 @@ import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Selection;
import org.hibernate.FetchClauseType;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.query.criteria.JpaCriteriaQuery;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
@ -58,6 +60,15 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
this.querySource = querySource;
}
public SqmSelectStatement(
SqmQueryPart<T> queryPart,
Class<T> resultType,
SqmQuerySource querySource,
NodeBuilder builder) {
super( queryPart, resultType, builder );
this.querySource = querySource;
}
/**
* @implNote This form is used from Hibernate's JPA criteria handling.
*/
@ -75,6 +86,52 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
return querySource;
}
@Override
public SqmQuerySpec<T> getQuerySpec() {
if ( querySource == SqmQuerySource.CRITERIA ) {
final SqmQueryPart<T> queryPart = getQueryPart();
if ( queryPart instanceof SqmQuerySpec<?> ) {
return (SqmQuerySpec<T>) queryPart;
}
throw new IllegalStateException(
"Query group can't be treated as query spec. Use JpaSelectCriteria#getQueryPart to access query group details"
);
}
else {
return super.getQuerySpec();
}
}
public boolean containsCollectionFetches() {
return containsCollectionFetches( getQueryPart() );
}
private boolean containsCollectionFetches(SqmQueryPart<?> queryPart) {
if ( queryPart instanceof SqmQuerySpec<?> ) {
return ( (SqmQuerySpec<?>) queryPart ).containsCollectionFetches();
}
else {
// We only have to check the first one
final SqmQueryGroup<?> queryGroup = (SqmQueryGroup<?>) queryPart;
return containsCollectionFetches( queryGroup.getQueryParts().get( 0 ) );
}
}
public boolean usesDistinct() {
return usesDistinct( getQueryPart() );
}
private boolean usesDistinct(SqmQueryPart<?> queryPart) {
if ( queryPart instanceof SqmQuerySpec<?> ) {
return ( (SqmQuerySpec<?>) queryPart ).getSelectClause().isDistinct();
}
else {
// We only have to check the first one
final SqmQueryGroup<?> queryGroup = (SqmQueryGroup<?>) queryPart;
return usesDistinct( queryGroup.getQueryParts().get( 0 ) );
}
}
@Override
public Set<SqmParameter<?>> getSqmParameters() {
if ( querySource == SqmQuerySource.CRITERIA ) {
@ -265,7 +322,7 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
@Override
public SqmSelectStatement<T> multiselect(Selection<?>... selections) {
for ( Selection<?> selection : selections ) {
getQuerySpec().getSelectClause().add( (SqmExpression) selection, selection.getAlias() );
getQuerySpec().getSelectClause().add( (SqmExpression<?>) selection, selection.getAlias() );
}
setResultType( (Class<T>) Object[].class );
return this;
@ -274,7 +331,7 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
@Override
public SqmSelectStatement<T> multiselect(List<Selection<?>> selectionList) {
for ( Selection<?> selection : selectionList ) {
getQuerySpec().getSelectClause().add( (SqmExpression) selection, selection.getAlias() );
getQuerySpec().getSelectClause().add( (SqmExpression<?>) selection, selection.getAlias() );
}
setResultType( (Class<T>) Object[].class );
return this;
@ -282,22 +339,22 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
@Override
public SqmSelectStatement<T> orderBy(Order... orders) {
if ( getQuerySpec().getOrderByClause() == null ) {
getQuerySpec().setOrderByClause( new SqmOrderByClause() );
if ( getQueryPart().getOrderByClause() == null ) {
getQueryPart().setOrderByClause( new SqmOrderByClause() );
}
for ( Order order : orders ) {
getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order );
getQueryPart().getOrderByClause().addSortSpecification( (SqmSortSpecification) order );
}
return this;
}
@Override
public SqmSelectStatement<T> orderBy(List<Order> orders) {
if ( getQuerySpec().getOrderByClause() == null ) {
getQuerySpec().setOrderByClause( new SqmOrderByClause() );
if ( getQueryPart().getOrderByClause() == null ) {
getQueryPart().setOrderByClause( new SqmOrderByClause() );
}
for ( Order order : orders ) {
getQuerySpec().getOrderByClause().addSortSpecification( (SqmSortSpecification) order );
getQueryPart().getOrderByClause().addSortSpecification( (SqmSortSpecification) order );
}
return this;
}
@ -336,4 +393,55 @@ public class SqmSelectStatement<T> extends AbstractSqmSelectQuery<T> implements
public SqmSelectStatement<T> having(Predicate... predicates) {
return (SqmSelectStatement<T>) super.having( predicates );
}
@Override
public JpaExpression<Number> getOffset() {
return (JpaExpression<Number>) getQueryPart().getOffset();
}
@Override
public JpaCriteriaQuery<T> offset(JpaExpression<? extends Number> offset) {
getQueryPart().setOffset( offset );
return this;
}
@Override
public JpaCriteriaQuery<T> offset(Number offset) {
getQueryPart().setOffset( nodeBuilder().value( offset ) );
return this;
}
@Override
public JpaExpression<Number> getFetch() {
return (JpaExpression<Number>) getQueryPart().getFetch();
}
@Override
public JpaCriteriaQuery<T> fetch(JpaExpression<? extends Number> fetch) {
getQueryPart().setFetch( fetch );
return this;
}
@Override
public JpaCriteriaQuery<T> fetch(JpaExpression<? extends Number> fetch, FetchClauseType fetchClauseType) {
getQueryPart().setFetch( fetch, fetchClauseType );
return this;
}
@Override
public JpaCriteriaQuery<T> fetch(Number fetch) {
getQueryPart().setFetch( nodeBuilder().value( fetch ) );
return this;
}
@Override
public JpaCriteriaQuery<T> fetch(Number fetch, FetchClauseType fetchClauseType) {
getQueryPart().setFetch( nodeBuilder().value( fetch ), fetchClauseType );
return this;
}
@Override
public FetchClauseType getFetchClauseType() {
return getQueryPart().getFetchClauseType();
}
}

View File

@ -12,7 +12,7 @@ import java.util.ArrayList;
import java.util.List;
public class Values {
private List<Expression> expressions = new ArrayList<>();
private final List<Expression> expressions = new ArrayList<>();
public List<Expression> getExpressions() {
return expressions;

View File

@ -32,10 +32,10 @@ public class BasicTypeRegistry implements Serializable {
private final TypeConfiguration typeConfiguration;
private final Map<SqlTypeDescriptor,Map<JavaTypeDescriptor<?>,BasicType<?>>> registryValues = new ConcurrentHashMap<>();
private final Map<SqlTypeDescriptor, Map<JavaTypeDescriptor<?>, BasicType<?>>> registryValues = new ConcurrentHashMap<>();
private boolean primed;
private Map<String, BasicType> typesByName = new ConcurrentHashMap<>();
private final Map<String, BasicType<?>> typesByName = new ConcurrentHashMap<>();
public BasicTypeRegistry(TypeConfiguration typeConfiguration){
this.typeConfiguration = typeConfiguration;
@ -44,11 +44,12 @@ public class BasicTypeRegistry implements Serializable {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Access
public BasicType getRegisteredType(String key) {
return typesByName.get( key );
public <J> BasicType<J> getRegisteredType(String key) {
//noinspection unchecked
return (BasicType<J>) typesByName.get( key );
}
public BasicType getRegisteredType(Class javaType) {
public <J> BasicType<J> getRegisteredType(Class<J> javaType) {
return getRegisteredType( javaType.getName() );
}
@ -56,12 +57,12 @@ public class BasicTypeRegistry implements Serializable {
* Find an existing BasicType registration for the given JavaTypeDescriptor and
* SqlTypeDescriptor combo or create (and register) one.
*/
public BasicType<?> resolve(JavaTypeDescriptor<?> jtdToUse, SqlTypeDescriptor stdToUse) {
public <J> BasicType<J> resolve(JavaTypeDescriptor<J> jtdToUse, SqlTypeDescriptor stdToUse) {
//noinspection unchecked
return resolve(
jtdToUse,
stdToUse,
() -> new StandardBasicTypeImpl( jtdToUse, stdToUse )
() -> new StandardBasicTypeImpl<>( jtdToUse, stdToUse )
);
}
@ -69,28 +70,29 @@ public class BasicTypeRegistry implements Serializable {
* Find an existing BasicType registration for the given JavaTypeDescriptor and
* SqlTypeDescriptor combo or create (and register) one.
*/
public BasicType<?> resolve(JavaTypeDescriptor<?> jtdToUse, SqlTypeDescriptor stdToUse, Supplier<BasicType<?>> creator) {
public <J> BasicType<J> resolve(JavaTypeDescriptor<J> jtdToUse, SqlTypeDescriptor stdToUse, Supplier<BasicType<J>> creator) {
final Map<JavaTypeDescriptor<?>, BasicType<?>> typeByJtdForStd = registryValues.computeIfAbsent(
stdToUse,
sqlTypeDescriptor -> new ConcurrentHashMap<>()
);
return typeByJtdForStd.computeIfAbsent( jtdToUse, javaDescriptor -> creator.get() );
//noinspection unchecked
return (BasicType<J>) typeByJtdForStd.computeIfAbsent( jtdToUse, javaDescriptor -> creator.get() );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Mutations
public void register(BasicType type) {
public void register(BasicType<?> type) {
register( type, type.getRegistrationKeys() );
}
public void register(BasicType type, String key) {
public void register(BasicType<?> type, String key) {
typesByName.put( key, type );
}
public void register(BasicType type, String... keys) {
public void register(BasicType<?> type, String... keys) {
if ( ! isPrimed() ) {
throw new IllegalStateException( "BasicTypeRegistry not yet primed. Calls to `#register` not valid until after primed" );
}
@ -110,7 +112,7 @@ public class BasicTypeRegistry implements Serializable {
}
}
private void applyOrOverwriteEntry(BasicType type) {
private void applyOrOverwriteEntry(BasicType<?> type) {
final Map<JavaTypeDescriptor<?>, BasicType<?>> mappingsForStdToUse = registryValues.computeIfAbsent(
type.getSqlTypeDescriptor(),
sqlTypeDescriptor -> new ConcurrentHashMap<>()
@ -133,7 +135,7 @@ public class BasicTypeRegistry implements Serializable {
public void unregister(String... keys) {
for ( String key : keys ) {
final BasicType removed = typesByName.remove( key );
final BasicType<?> removed = typesByName.remove( key );
}
@ -151,7 +153,7 @@ public class BasicTypeRegistry implements Serializable {
this.primed = true;
}
public void addPrimeEntry(BasicType type, String legacyTypeClassName, String[] registrationKeys) {
public void addPrimeEntry(BasicType<?> type, String legacyTypeClassName, String[] registrationKeys) {
if ( primed ) {
throw new IllegalStateException( "BasicTypeRegistry already primed" );
}
@ -176,7 +178,7 @@ public class BasicTypeRegistry implements Serializable {
}
}
private void primeRegistryEntry(BasicType type) {
private void primeRegistryEntry(BasicType<?> type) {
final Map<JavaTypeDescriptor<?>, BasicType<?>> mappingsForStdToUse = registryValues.computeIfAbsent(
type.getSqlTypeDescriptor(),
sqlTypeDescriptor -> new ConcurrentHashMap<>()
@ -197,7 +199,7 @@ public class BasicTypeRegistry implements Serializable {
}
}
private void applyRegistrationKeys(BasicType type, String[] keys) {
private void applyRegistrationKeys(BasicType<?> type, String[] keys) {
for ( String key : keys ) {
// be safe...
if ( key == null ) {

View File

@ -541,22 +541,22 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
}
}
@SuppressWarnings("unchecked")
private static boolean matchesJavaType(SqmExpressable type, Class javaType) {
private static boolean matchesJavaType(SqmExpressable<?> type, Class<?> javaType) {
assert javaType != null;
return type != null && javaType.isAssignableFrom( type.getExpressableJavaTypeDescriptor().getJavaType() );
}
private final ConcurrentHashMap<Class,BasicType> basicTypeByJavaType = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Class<?>, BasicType<?>> basicTypeByJavaType = new ConcurrentHashMap<>();
public BasicType getBasicTypeForJavaType(Class<?> javaType) {
final BasicType existing = basicTypeByJavaType.get( javaType );
public <J> BasicType<J> getBasicTypeForJavaType(Class<J> javaType) {
final BasicType<?> existing = basicTypeByJavaType.get( javaType );
if ( existing != null ) {
return existing;
//noinspection unchecked
return (BasicType<J>) existing;
}
final BasicType registeredType = getBasicTypeRegistry().getRegisteredType( javaType );
final BasicType<J> registeredType = getBasicTypeRegistry().getRegisteredType( javaType );
if ( registeredType != null ) {
basicTypeByJavaType.put( javaType, registeredType );
return registeredType;
@ -565,7 +565,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
return null;
}
public BasicType standardBasicTypeForJavaType(Class<?> javaType) {
public <J> BasicType<J> standardBasicTypeForJavaType(Class<J> javaType) {
if ( javaType == null ) {
return null;
}
@ -573,48 +573,49 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
//noinspection unchecked
return standardBasicTypeForJavaType(
javaType,
javaTypeDescriptor -> new StandardBasicTypeImpl(
javaTypeDescriptor -> new StandardBasicTypeImpl<>(
javaTypeDescriptor,
javaTypeDescriptor.getJdbcRecommendedSqlType( getCurrentBaseSqlTypeIndicators() )
)
);
}
public BasicType standardBasicTypeForJavaType(
Class<?> javaType,
Function<JavaTypeDescriptor<?>,BasicType> creator) {
public <J> BasicType<J> standardBasicTypeForJavaType(
Class<J> javaType,
Function<JavaTypeDescriptor<J>, BasicType<J>> creator) {
if ( javaType == null ) {
return null;
}
return basicTypeByJavaType.computeIfAbsent(
//noinspection unchecked
return (BasicType<J>) basicTypeByJavaType.computeIfAbsent(
javaType,
jt -> {
// See if one exists in the BasicTypeRegistry and use that one if so
final BasicType registeredType = basicTypeRegistry.getRegisteredType( javaType );
final BasicType<J> registeredType = basicTypeRegistry.getRegisteredType( javaType );
if ( registeredType != null ) {
return registeredType;
}
// otherwise, apply the creator
final JavaTypeDescriptor javaTypeDescriptor = javaTypeDescriptorRegistry.resolveDescriptor( javaType );
final JavaTypeDescriptor<J> javaTypeDescriptor = javaTypeDescriptorRegistry.resolveDescriptor( javaType );
return creator.apply( javaTypeDescriptor );
}
);
}
public TemporalType getSqlTemporalType(SqmExpressable type) {
public TemporalType getSqlTemporalType(SqmExpressable<?> type) {
if ( type == null ) {
return null;
}
return getSqlTemporalType( type.getExpressableJavaTypeDescriptor().getJdbcRecommendedSqlType( getCurrentBaseSqlTypeIndicators() ) );
}
public static TemporalType getSqlTemporalType(MappingModelExpressable type) {
public static TemporalType getSqlTemporalType(MappingModelExpressable<?> type) {
if ( type instanceof BasicValuedMapping ) {
return getSqlTemporalType( ( (BasicValuedMapping) type ).getJdbcMapping().getSqlTypeDescriptor() );
}
else if (type instanceof SingleColumnType) {
return getSqlTemporalType( ((SingleColumnType) type).sqlType() );
return getSqlTemporalType( ((SingleColumnType<?>) type).sqlType() );
}
return null;
}

View File

@ -369,12 +369,12 @@ public class CriteriaEntityGraphTest implements SessionFactoryScopeAware {
final HqlQueryImplementor<String> hqlQuery = (HqlQueryImplementor<String>) query;
hqlQuery.applyGraph( entityGraph, mode );
final SqmSelectStatement sqmStatement = (SqmSelectStatement) hqlQuery.getSqmStatement();
final SqmSelectStatement<String> sqmStatement = (SqmSelectStatement<String>) hqlQuery.getSqmStatement();
final StandardSqmTranslator<SelectStatement> sqmConverter = new StandardSqmTranslator<>(
sqmStatement,
hqlQuery.getQueryOptions(),
( (QuerySqmImpl) hqlQuery ).getDomainParameterXref(),
( (QuerySqmImpl<?>) hqlQuery ).getDomainParameterXref(),
query.getParameterBindings(),
loadQueryInfluencers,
session.getSessionFactory()

View File

@ -365,12 +365,12 @@ public class HqlEntityGraphTest implements SessionFactoryScopeAware {
final HqlQueryImplementor<String> hqlQuery = (HqlQueryImplementor<String>) query;
hqlQuery.applyGraph( entityGraph, mode );
final SqmSelectStatement sqmStatement = (SqmSelectStatement) hqlQuery.getSqmStatement();
final SqmSelectStatement<String> sqmStatement = (SqmSelectStatement<String>) hqlQuery.getSqmStatement();
final StandardSqmTranslator<SelectStatement> sqmConverter = new StandardSqmTranslator<>(
sqmStatement,
hqlQuery.getQueryOptions(),
( (QuerySqmImpl) hqlQuery ).getDomainParameterXref(),
( (QuerySqmImpl<?>) hqlQuery ).getDomainParameterXref(),
query.getParameterBindings(),
loadQueryInfluencers,
session.getSessionFactory()

View File

@ -56,7 +56,7 @@ public class HqlTranslationNoFactoryTests {
final String hql = "select a from SalesAssociate a";
final HqlTranslator hqlTranslator = buildHqlTranslator( modelScope, registryScope );
final SqmStatement sqmStatement = hqlTranslator.translate( hql );
final SqmStatement<?> sqmStatement = hqlTranslator.translate( hql );
assert sqmStatement != null;
}

View File

@ -89,9 +89,9 @@ public class AliasCollisionTest extends BaseSqmUnitTest {
@Test
public void testSameIdentificationVariablesInSubquery() {
final String query = "select a from SimpleEntity a where a.someString in (select a.someString from SimpleEntity a where a.someInteger = 5)";
final SqmSelectStatement sqm = interpretSelect( query );
final SqmSelectStatement<?> sqm = interpretSelect( query );
final SqmQuerySpec querySpec = sqm.getQuerySpec();
final SqmQuerySpec<?> querySpec = sqm.getQuerySpec();
final List<SqmSelection> selections = querySpec.getSelectClause().getSelections();
assertThat( selections, hasSize( 1 ) );
@ -118,9 +118,9 @@ public class AliasCollisionTest extends BaseSqmUnitTest {
public void testSubqueryUsingIdentificationVariableDefinedInRootQuery() {
final String query = "select a from SimpleEntity a where a.someString in " +
"( select b.someString from SimpleEntity b where a.someLong = b.someLong )";
final SqmSelectStatement sqm = interpretSelect( query );
final SqmSelectStatement<?> sqm = interpretSelect( query );
final SqmQuerySpec querySpec = sqm.getQuerySpec();
final SqmQuerySpec<?> querySpec = sqm.getQuerySpec();
final List<SqmSelection> selections = querySpec.getSelectClause().getSelections();
assertThat( selections, hasSize( 1 ) );

View File

@ -47,7 +47,7 @@ public class AttributePathTests extends BaseSqmUnitTest {
@Test
public void testImplicitJoinReuse() {
final SqmSelectStatement statement = interpretSelect( "select s.mate.dob, s.mate.numberOfToes from Person s" );
final SqmSelectStatement<?> statement = interpretSelect( "select s.mate.dob, s.mate.numberOfToes from Person s" );
assertThat( statement.getQuerySpec().getFromClause().getRoots().size(), is(1) );
final SqmRoot<?> sqmRoot = statement.getQuerySpec().getFromClause().getRoots().get( 0 );
@ -75,7 +75,7 @@ public class AttributePathTests extends BaseSqmUnitTest {
@Test
public void testImplicitJoinReuse2() {
final SqmSelectStatement statement = interpretSelect( "select s.mate from Person s where s.mate.dob = ?1" );
final SqmSelectStatement<?> statement = interpretSelect( "select s.mate from Person s where s.mate.dob = ?1" );
assertThat( statement.getQuerySpec().getFromClause().getRoots().size(), is(1) );
final SqmRoot<?> sqmRoot = statement.getQuerySpec().getFromClause().getRoots().get( 0 );
@ -114,20 +114,20 @@ public class AttributePathTests extends BaseSqmUnitTest {
.entity( OddOne.class );
final SingularPersistentAttribute<OddOne, ?> idAttribute = entity.findIdAttribute();
final SqmSelectStatement sqmSelectStatement = interpretSelect( "select s.id from OddOne s where s.pk = ?1" );
final SqmSelectStatement<?> sqmSelectStatement = interpretSelect( "select s.id from OddOne s where s.pk = ?1" );
final SqmQuerySpec querySpec = sqmSelectStatement.getQuerySpec();
final SqmQuerySpec<?> querySpec = sqmSelectStatement.getQuerySpec();
assertThat( querySpec.getSelectClause().getSelections().size(), is(1) );
final SqmSelection sqmSelection = querySpec.getSelectClause().getSelections().get( 0 );
final SqmSelection<?> sqmSelection = querySpec.getSelectClause().getSelections().get( 0 );
assertThat( sqmSelection.getSelectableNode(), not( sameInstance( idAttribute ) ) );
final SqmExpression<?> pkRef = ( (SqmComparisonPredicate) querySpec.getRestriction() ).getLeftHandExpression();
assertThat( ( (SqmPath) pkRef ).getJavaType(), sameInstance( String.class ) );
assertThat( ( (SqmPath<?>) pkRef ).getJavaType(), sameInstance( String.class ) );
}
@Test
public void testCanonicalReferences() {
final SqmSelectStatement sqm = interpretSelect( "select s.mate from Person s where id(s) = ?1" );
final SqmSelectStatement<?> sqm = interpretSelect( "select s.mate from Person s where id(s) = ?1" );
assertThat( sqm.getQuerySpec().getRestriction(), notNullValue() );
final SqmComparisonPredicate restriction = (SqmComparisonPredicate) sqm.getQuerySpec().getRestriction();
assertThat( restriction, notNullValue() );
@ -135,11 +135,11 @@ public class AttributePathTests extends BaseSqmUnitTest {
@Test
public void testManyToOneReference() {
final SqmSelectStatement sqm = interpretSelect( "select s.mate from Person s" );
final SqmSelectStatement<?> sqm = interpretSelect( "select s.mate from Person s" );
final List<SqmSelection> selections = sqm.getQuerySpec().getSelectClause().getSelections();
assertThat( selections.size(), is( 1 ) );
final SqmSelection selection = selections.get( 0 );
final SqmSelectableNode selectableNode = selection.getSelectableNode();
final SqmSelection<?> selection = selections.get( 0 );
final SqmSelectableNode<?> selectableNode = selection.getSelectableNode();
assert Person.class.equals( selectableNode.getJavaTypeDescriptor().getJavaType() );
}

View File

@ -40,7 +40,7 @@ public class CaseExpressionsTest extends BaseSqmUnitTest {
@Test
public void testBasicSimpleCaseExpression() {
SqmSelectStatement select = interpretSelect(
SqmSelectStatement<?> select = interpretSelect(
"select p from Person p where p.numberOfToes = case p.dob when ?1 then 6 else 8 end"
);
@ -65,7 +65,7 @@ public class CaseExpressionsTest extends BaseSqmUnitTest {
@Test
public void testBasicSearchedCaseExpression() {
SqmSelectStatement select = interpretSelect(
SqmSelectStatement<?> select = interpretSelect(
"select p from Person p where p.numberOfToes = case when p.dob = ?1 then 6 else 8 end"
);
@ -87,7 +87,7 @@ public class CaseExpressionsTest extends BaseSqmUnitTest {
@Test
public void testBasicCoalesceExpression() {
SqmSelectStatement select = interpretSelect(
SqmSelectStatement<?> select = interpretSelect(
"select coalesce(p.nickName, p.mate.nickName) from Person p"
);
@ -104,7 +104,7 @@ public class CaseExpressionsTest extends BaseSqmUnitTest {
@Test
public void testBasicNullifExpression() {
SqmSelectStatement select = interpretSelect(
SqmSelectStatement<?> select = interpretSelect(
"select nullif(p.nickName, p.mate.nickName) from Person p"
);

View File

@ -45,7 +45,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
@Test
public void testSimpleDynamicInstantiationSelection() {
SqmSelectStatement statement = interpretSelect(
SqmSelectStatement<?> statement = interpretSelect(
"select new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ) from EntityOfBasics e"
);
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
@ -62,7 +62,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
@Test
public void testMultipleDynamicInstantiationSelection() {
SqmSelectStatement statement = interpretSelect(
SqmSelectStatement<?> statement = interpretSelect(
"select new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ), " +
"new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ) " +
"from EntityOfBasics e"
@ -99,7 +99,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
@Test
public void testMixedAttributeAndDynamicInstantiationSelection() {
SqmSelectStatement statement = interpretSelect(
SqmSelectStatement<?> statement = interpretSelect(
"select new org.hibernate.orm.test.query.sqm.domain.ConstructedLookupListItem( e.id, e.theString ), e.theInteger from EntityOfBasics e"
);
assertEquals( 2, statement.getQuerySpec().getSelectClause().getSelections().size() );
@ -117,7 +117,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
assertThat( instantiation.getArguments(), hasSize( 2 ) );
final SqmPath theIntegerPath = TestingUtil.cast(
final SqmPath<?> theIntegerPath = TestingUtil.cast(
statement.getQuerySpec().getSelectClause().getSelections().get( 1 ).getSelectableNode(),
SqmPath.class
);
@ -127,7 +127,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
@Test
public void testNestedDynamicInstantiationSelection() {
SqmSelectStatement statement = interpretSelect(
SqmSelectStatement<?> statement = interpretSelect(
"select new org.hibernate.orm.test.query.sqm.domain.NestedCtorLookupListItem(" +
" e.id, " +
" e.theString, " +
@ -154,7 +154,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
);
assertThat( firstArg.getReferencedPathSource().getPathName(), is( "id" ) );
final SqmPath secondArg = TestingUtil.cast(
final SqmPath<?> secondArg = TestingUtil.cast(
instantiation.getArguments().get( 1 ).getSelectableNode(),
SqmPath.class
);
@ -175,7 +175,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
@Test
public void testSimpleDynamicListInstantiation() {
SqmSelectStatement statement = interpretSelect( "select new list( e.id, e.theString ) from EntityOfBasics e" );
SqmSelectStatement<?> statement = interpretSelect( "select new list( e.id, e.theString ) from EntityOfBasics e" );
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmDynamicInstantiation<?> instantiation = TestingUtil.cast(
@ -208,7 +208,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
@Test
public void testSimpleDynamicMapInstantiation() {
SqmSelectStatement statement = interpretSelect( "select new map( e.id as id, e.theString as ts ) from EntityOfBasics e" );
SqmSelectStatement<?> statement = interpretSelect( "select new map( e.id as id, e.theString as ts ) from EntityOfBasics e" );
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmDynamicInstantiation<?> instantiation = TestingUtil.cast(
@ -245,7 +245,7 @@ public class DynamicInstantiationTests extends BaseSqmUnitTest {
// todo (6.0) : this should blow up as early as possible - no aliases for bean-injection-based dynamic-instantiation
// atm this does not fail until later when building the SQL AST
SqmSelectStatement statement = interpretSelect(
SqmSelectStatement<?> statement = interpretSelect(
"select new org.hibernate.orm.test.query.sqm.domain.InjectedLookupListItem( e.id, e.theString ) from EntityOfBasics e"
);
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );

View File

@ -47,7 +47,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testSimpleFrom() {
final SqmSelectStatement selectStatement = interpretSelect( "select p.nickName from Person p" );
final SqmSelectStatement<?> selectStatement = interpretSelect( "select p.nickName from Person p" );
final SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause();
assertThat( fromClause, notNullValue() );
@ -61,7 +61,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testMultipleSpaces() {
final SqmSelectStatement selectStatement = interpretSelect(
final SqmSelectStatement<?> selectStatement = interpretSelect(
"select p.nickName from Person p, Person p2"
);
@ -85,7 +85,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testImplicitAlias() {
final SqmSelectStatement selectStatement = interpretSelect( "select nickName from Person" );
final SqmSelectStatement<?> selectStatement = interpretSelect( "select nickName from Person" );
final SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause();
assertThat( fromClause, notNullValue() );
@ -99,7 +99,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testCrossJoin() {
final SqmSelectStatement selectStatement = interpretSelect(
final SqmSelectStatement<?> selectStatement = interpretSelect(
"select p.nickName from Person p cross join Person p2"
);
@ -125,7 +125,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
}
private void simpleJoinAssertions(
SqmSelectStatement selectStatement,
SqmSelectStatement<?> selectStatement,
SqmJoinType joinType,
String rootAlias,
String joinAlias) {
@ -174,7 +174,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testAttributeJoinWithOnClause() {
final SqmSelectStatement selectStatement = interpretSelect(
final SqmSelectStatement<?> selectStatement = interpretSelect(
"select a from Person a left outer join a.mate c on c.numberOfToes > 5 and c.numberOfToes < 20 "
);
@ -199,7 +199,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testPathExpression() {
final String query = "select p.mate from Person p";
SqmSelectStatement selectStatement = interpretSelect( query );
SqmSelectStatement<?> selectStatement = interpretSelect( query );
final SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause();
@ -215,7 +215,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testFromElementReferenceInSelect() {
final String query = "select p from Person p";
SqmSelectStatement selectStatement = interpretSelect( query );
SqmSelectStatement<?> selectStatement = interpretSelect( query );
final SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause();
assertThat( fromClause, notNullValue() );
@ -225,7 +225,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
assertThat( sqmRoot, notNullValue() );
assertThat( selectStatement.getQuerySpec().getSelectClause().getSelections(), hasSize( 1 ) );
final SqmSelection sqmSelection = selectStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
final SqmSelection<?> sqmSelection = selectStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
assertThat( sqmSelection.getSelectableNode(), instanceOf( SqmRoot.class ) );
}
@ -233,7 +233,7 @@ public class FromClauseTests extends BaseSqmUnitTest {
@Test
public void testFromElementReferenceInOrderBy() {
final String query = "select p from Person p order by p";
SqmSelectStatement selectStatement = interpretSelect( query );
SqmSelectStatement<?> selectStatement = interpretSelect( query );
final SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause();
assertThat( fromClause, notNullValue() );

View File

@ -33,7 +33,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
public class MutationTests {
@Test
public void testSimpleDeleteTranslation(SessionFactoryScope scope) {
final SqmDeleteStatement sqmDelete = (SqmDeleteStatement) scope.getSessionFactory()
final SqmDeleteStatement<?> sqmDelete = (SqmDeleteStatement<?>) scope.getSessionFactory()
.getQueryEngine()
.getHqlTranslator()
.translate( "delete BasicEntity" );
@ -45,7 +45,7 @@ public class MutationTests {
@Test
public void testSimpleRestrictedDeleteTranslation(SessionFactoryScope scope) {
final SqmDeleteStatement sqmDelete = (SqmDeleteStatement) scope.getSessionFactory()
final SqmDeleteStatement<?> sqmDelete = (SqmDeleteStatement<?>) scope.getSessionFactory()
.getQueryEngine()
.getHqlTranslator()
.translate( "delete BasicEntity where data = 'abc'" );

View File

@ -82,7 +82,7 @@ public class ParameterTests extends BaseSqmUnitTest {
@Test
public void testAllowMultiValuedBinding() {
final SqmSelectStatement<?> sqm = interpretSelect( "select a.nickName from Person a where a.numberOfToes in (?1)" );
final SqmParameter parameter = sqm.getSqmParameters().iterator().next();
final SqmParameter<?> parameter = sqm.getSqmParameters().iterator().next();
assertThat( parameter.allowMultiValuedBinding(), is(true) );
}

View File

@ -54,23 +54,23 @@ public class SelectClauseTests extends BaseSqmUnitTest {
@Test
public void testSimpleAliasSelection() {
SqmSelectStatement statement = interpretSelect( "select p from Person p" );
SqmSelectStatement<?> statement = interpretSelect( "select p from Person p" );
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
SqmSelection selection = statement.getQuerySpec().getSelectClause().getSelections().get( 0 );
SqmSelection<?> selection = statement.getQuerySpec().getSelectClause().getSelections().get( 0 );
assertThat( selection.getSelectableNode(), instanceOf( SqmRoot.class ) );
}
@Test
public void testSimpleAttributeSelection() {
SqmSelectStatement statement = interpretSelect( "select p.nickName from Person p" );
SqmSelectStatement<?> statement = interpretSelect( "select p.nickName from Person p" );
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
SqmSelection selection = statement.getQuerySpec().getSelectClause().getSelections().get( 0 );
SqmSelection<?> selection = statement.getQuerySpec().getSelectClause().getSelections().get( 0 );
assertThat( selection.getSelectableNode(), instanceOf( SqmSimplePath.class ) );
}
@Test
public void testCompoundAttributeSelection() {
SqmSelectStatement statement = interpretSelect( "select p.nickName, p.name.firstName from Person p" );
SqmSelectStatement<?> statement = interpretSelect( "select p.nickName, p.name.firstName from Person p" );
assertEquals( 2, statement.getQuerySpec().getSelectClause().getSelections().size() );
assertThat(
statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(),
@ -84,7 +84,7 @@ public class SelectClauseTests extends BaseSqmUnitTest {
@Test
public void testMixedAliasAndAttributeSelection() {
SqmSelectStatement statement = interpretSelect( "select p, p.nickName from Person p" );
SqmSelectStatement<?> statement = interpretSelect( "select p, p.nickName from Person p" );
assertEquals( 2, statement.getQuerySpec().getSelectClause().getSelections().size() );
assertThat(
statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(),
@ -99,10 +99,10 @@ public class SelectClauseTests extends BaseSqmUnitTest {
@Test
public void testBinaryArithmeticExpression() {
final String query = "select p.numberOfToes + p.numberOfToes as b from Person p";
final SqmSelectStatement selectStatement = interpretSelect( query );
final SqmSelectStatement<?> selectStatement = interpretSelect( query );
final SqmQuerySpec querySpec = selectStatement.getQuerySpec();
final SqmSelection selection = querySpec.getSelectClause().getSelections().get( 0 );
final SqmQuerySpec<?> querySpec = selectStatement.getQuerySpec();
final SqmSelection<?> selection = querySpec.getSelectClause().getSelections().get( 0 );
assertThat( querySpec.getFromClause().getRoots().size(), is(1) );
final SqmRoot<?> root = querySpec.getFromClause().getRoots().get( 0 );
@ -110,12 +110,12 @@ public class SelectClauseTests extends BaseSqmUnitTest {
assertThat( root.getJoins().size(), is(0) );
SqmBinaryArithmetic expression = (SqmBinaryArithmetic) selection.getSelectableNode();
SqmPath leftHandOperand = (SqmPath) expression.getLeftHandOperand();
SqmPath<?> leftHandOperand = (SqmPath<?>) expression.getLeftHandOperand();
assertThat( leftHandOperand.getLhs(), sameInstance( root ) );
assertThat( leftHandOperand.getReferencedPathSource().getPathName(), is( "numberOfToes" ) );
// assertThat( leftHandOperand.getFromElement(), nullValue() );
SqmPath rightHandOperand = (SqmPath) expression.getRightHandOperand();
SqmPath<?> rightHandOperand = (SqmPath<?>) expression.getRightHandOperand();
assertThat( rightHandOperand.getLhs(), sameInstance( root ) );
assertThat( rightHandOperand.getReferencedPathSource().getPathName(), is( "numberOfToes" ) );
// assertThat( leftHandOperand.getFromElement(), nullValue() );
@ -124,10 +124,10 @@ public class SelectClauseTests extends BaseSqmUnitTest {
@Test
public void testBinaryArithmeticExpressionWithMultipleFromSpaces() {
final String query = "select p.numberOfToes + p2.numberOfToes as b from Person p, Person p2";
final SqmSelectStatement selectStatement = interpretSelect( query );
final SqmSelectStatement<?> selectStatement = interpretSelect( query );
final SqmQuerySpec querySpec = selectStatement.getQuerySpec();
final SqmSelection selection = querySpec.getSelectClause().getSelections().get( 0 );
final SqmQuerySpec<?> querySpec = selectStatement.getQuerySpec();
final SqmSelection<?> selection = querySpec.getSelectClause().getSelections().get( 0 );
assertThat( querySpec.getFromClause().getRoots().size(), is(2) );
@ -139,11 +139,11 @@ public class SelectClauseTests extends BaseSqmUnitTest {
SqmBinaryArithmetic addExpression = (SqmBinaryArithmetic) selection.getSelectableNode();
SqmPath leftHandOperand = (SqmPath) addExpression.getLeftHandOperand();
SqmPath<?> leftHandOperand = (SqmPath<?>) addExpression.getLeftHandOperand();
assertThat( leftHandOperand.getLhs(), sameInstance( entityRoot ) );
assertThat( leftHandOperand.getReferencedPathSource().getPathName(), is( "numberOfToes" ) );
SqmPath rightHandOperand = (SqmPath) addExpression.getRightHandOperand();
SqmPath<?> rightHandOperand = (SqmPath<?>) addExpression.getRightHandOperand();
assertThat( rightHandOperand.getLhs(), sameInstance( entity2Root ) );
assertThat( rightHandOperand.getReferencedPathSource().getPathName(), is( "numberOfToes" ) );
}
@ -165,20 +165,20 @@ public class SelectClauseTests extends BaseSqmUnitTest {
}
private void collectionIndexFunctionAssertions(
SqmSelectStatement statement,
SqmSelectStatement<?> statement,
CollectionClassification expectedCollectionClassification,
Class<? extends SimpleDomainType> expectedIndexDomainTypeType,
String expectedAlias) {
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmSelectableNode selectedExpr = statement.getQuerySpec()
final SqmSelectableNode<?> selectedExpr = statement.getQuerySpec()
.getSelectClause()
.getSelections()
.get( 0 )
.getSelectableNode();
assertThat( selectedExpr, instanceOf( SqmSimplePath.class ) );
final SqmSimplePath selectedPath = (SqmSimplePath) selectedExpr;
final SqmSimplePath<?> selectedPath = (SqmSimplePath<?>) selectedExpr;
assertThat( selectedPath.getLhs().getExplicitAlias(), is( expectedAlias ) );
@ -257,20 +257,20 @@ public class SelectClauseTests extends BaseSqmUnitTest {
}
private void collectionValueFunctionAssertions(
SqmSelectStatement statement,
SqmSelectStatement<?> statement,
String collectionRole,
String collectionIdentificationVariable) {
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmSelectableNode selectedExpression = statement.getQuerySpec()
final SqmSelectableNode<?> selectedExpression = statement.getQuerySpec()
.getSelectClause()
.getSelections()
.get( 0 )
.getSelectableNode();
assertThat( selectedExpression, instanceOf( SqmPath.class ) );
final SqmPath selectedPath = (SqmPath) selectedExpression;
final SqmPathSource referencedPathSource = selectedPath.getReferencedPathSource();
final SqmPath<?> selectedPath = (SqmPath<?>) selectedExpression;
final SqmPathSource<?> referencedPathSource = selectedPath.getReferencedPathSource();
final String ownerName = StringHelper.qualifier( collectionRole );
final String attributeName = StringHelper.unqualify( collectionRole );
@ -289,7 +289,7 @@ public class SelectClauseTests extends BaseSqmUnitTest {
testMapEntryFunctionAssertions( interpretSelect( "select entry(m) from EntityOfMaps e join e.sortedManyToManyByBasic m" ) );
}
private void testMapEntryFunctionAssertions(SqmSelectStatement statement) {
private void testMapEntryFunctionAssertions(SqmSelectStatement<?> statement) {
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmMapEntryReference mapEntryPath = (SqmMapEntryReference) statement.getQuerySpec()
@ -300,16 +300,16 @@ public class SelectClauseTests extends BaseSqmUnitTest {
assertThat( mapEntryPath.getJavaTypeDescriptor().getJavaType(), is( equalTo( Map.Entry.class ) ) );
final SqmPath selectedPathLhs = mapEntryPath.getMapPath();
final SqmPath<?> selectedPathLhs = mapEntryPath.getMapPath();
assertThat( selectedPathLhs.getExplicitAlias(), is( "m" ) );
}
@Test
public void testSimpleRootEntitySelection() {
SqmSelectStatement statement = interpretSelect( "select e from EntityOfBasics e" );
SqmSelectStatement<?> statement = interpretSelect( "select e from EntityOfBasics e" );
assertEquals( 1, statement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmPath sqmEntityReference = TestingUtil.cast(
final SqmPath<?> sqmEntityReference = TestingUtil.cast(
statement.getQuerySpec().getSelectClause().getSelections().get( 0 ).getSelectableNode(),
SqmPath.class
);

View File

@ -49,7 +49,7 @@ public class WhereClauseTests extends BaseSqmUnitTest {
@Test
public void testIsNotNullPredicate() {
SqmSelectStatement statement = interpretSelect( "select l from Person l where l.nickName is not null" );
SqmSelectStatement<?> statement = interpretSelect( "select l from Person l where l.nickName is not null" );
assertThat( statement.getQuerySpec().getWhereClause().getPredicate(), instanceOf( SqmNullnessPredicate.class ) );
SqmNullnessPredicate predicate = (SqmNullnessPredicate) statement.getQuerySpec().getWhereClause().getPredicate();
assertThat( predicate.isNegated(), is(true) );
@ -57,7 +57,7 @@ public class WhereClauseTests extends BaseSqmUnitTest {
@Test
public void testNotIsNullPredicate() {
SqmSelectStatement statement = interpretSelect( "select l from Person l where not l.nickName is null" );
SqmSelectStatement<?> statement = interpretSelect( "select l from Person l where not l.nickName is null" );
assertThat( statement.getQuerySpec().getWhereClause().getPredicate(), instanceOf( SqmNullnessPredicate.class ) );
SqmNullnessPredicate predicate = (SqmNullnessPredicate) statement.getQuerySpec().getWhereClause().getPredicate();
assertThat( predicate.isNegated(), is(true) );
@ -65,7 +65,7 @@ public class WhereClauseTests extends BaseSqmUnitTest {
@Test
public void testNotIsNotNullPredicate() {
SqmSelectStatement statement = interpretSelect( "select l from Person l where not l.nickName is not null" );
SqmSelectStatement<?> statement = interpretSelect( "select l from Person l where not l.nickName is not null" );
assertThat( statement.getQuerySpec().getWhereClause().getPredicate(), instanceOf( SqmNullnessPredicate.class ) );
SqmNullnessPredicate predicate = (SqmNullnessPredicate) statement.getQuerySpec().getWhereClause().getPredicate();
assertThat( predicate.isNegated(), is(false) );
@ -73,7 +73,7 @@ public class WhereClauseTests extends BaseSqmUnitTest {
@Test
public void testCollectionSizeFunction() {
SqmSelectStatement statement = interpretSelect( "SELECT t FROM EntityOfSets t WHERE SIZE( t.setOfBasics ) = 311" );
SqmSelectStatement<?> statement = interpretSelect( "SELECT t FROM EntityOfSets t WHERE SIZE( t.setOfBasics ) = 311" );
SqmPredicate predicate = statement.getQuerySpec().getWhereClause().getPredicate();
assertThat( predicate, instanceOf( SqmComparisonPredicate.class ) );
@ -82,7 +82,7 @@ public class WhereClauseTests extends BaseSqmUnitTest {
assertThat( relationalPredicate.getSqmOperator(), is( ComparisonOperator.EQUAL ) );
assertThat( relationalPredicate.getRightHandExpression(), instanceOf( SqmLiteral.class ) );
assertThat( ( (SqmLiteral) relationalPredicate.getRightHandExpression() ).getLiteralValue(), is( 311 ) );
assertThat( ( (SqmLiteral<?>) relationalPredicate.getRightHandExpression() ).getLiteralValue(), is( 311 ) );
assertThat( relationalPredicate.getLeftHandExpression(), instanceOf( SqmCollectionSize.class ) );
@ -93,7 +93,7 @@ public class WhereClauseTests extends BaseSqmUnitTest {
@Test
public void testListIndexFunction() {
SqmSelectStatement statement = interpretSelect( "select l from EntityOfLists t join t.listOfBasics l where index(l) > 2" );
SqmSelectStatement<?> statement = interpretSelect( "select l from EntityOfLists t join t.listOfBasics l where index(l) > 2" );
SqmPredicate predicate = statement.getQuerySpec().getWhereClause().getPredicate();
assertThat( predicate, instanceOf( SqmComparisonPredicate.class ) );
@ -102,10 +102,10 @@ public class WhereClauseTests extends BaseSqmUnitTest {
assertThat( relationalPredicate.getSqmOperator(), is( ComparisonOperator.GREATER_THAN ) );
assertThat( relationalPredicate.getRightHandExpression(), instanceOf( SqmLiteral.class ) );
assertThat( ( (SqmLiteral) relationalPredicate.getRightHandExpression() ).getLiteralValue(), is( 2 ) );
assertThat( ( (SqmLiteral<?>) relationalPredicate.getRightHandExpression() ).getLiteralValue(), is( 2 ) );
assertThat( relationalPredicate.getLeftHandExpression(), instanceOf( SqmPath.class ) );
final SqmPath indexPath = (SqmPath) relationalPredicate.getLeftHandExpression();
final SqmPath<?> indexPath = (SqmPath<?>) relationalPredicate.getLeftHandExpression();
assertThat( indexPath.getLhs(), notNullValue() );
assertThat( indexPath.getLhs().getExplicitAlias(), is( "l" ) );

View File

@ -48,12 +48,12 @@ public abstract class BaseSqmUnitTest
public void registerAfterLoadAction(AfterLoadAction afterLoadAction) {
}
protected SqmSelectStatement interpretSelect(String hql) {
protected SqmSelectStatement<?> interpretSelect(String hql) {
return interpretSelect( hql, sessionFactory() );
}
public static SqmSelectStatement interpretSelect(String hql, SessionFactoryImplementor sessionFactory) {
return (SqmSelectStatement) sessionFactory.getQueryEngine().getHqlTranslator().translate( hql );
public static SqmSelectStatement<?> interpretSelect(String hql, SessionFactoryImplementor sessionFactory) {
return (SqmSelectStatement<?>) sessionFactory.getQueryEngine().getHqlTranslator().translate( hql );
}
@Override

View File

@ -52,7 +52,7 @@ public class IdSelectionTests {
@Test
public void testSecondaryTableRestrictedOnRootTable(SessionFactoryScope scope) {
final SqmDeleteStatement sqm = (SqmDeleteStatement) scope.getSessionFactory()
final SqmDeleteStatement<?> sqm = (SqmDeleteStatement<?>) scope.getSessionFactory()
.getQueryEngine()
.getHqlTranslator()
.translate( "delete SimpleEntityWithSecondaryTables where name = :n" );
@ -77,7 +77,7 @@ public class IdSelectionTests {
@Test
public void testSecondaryTableRestrictedOnNonRootTable(SessionFactoryScope scope) {
final SqmDeleteStatement sqm = (SqmDeleteStatement) scope.getSessionFactory()
final SqmDeleteStatement<?> sqm = (SqmDeleteStatement<?>) scope.getSessionFactory()
.getQueryEngine()
.getHqlTranslator()
.translate( "delete SimpleEntityWithSecondaryTables where data = :d" );
@ -102,7 +102,7 @@ public class IdSelectionTests {
@Test
public void testJoinedSubclassRestrictedOnRootTable(SessionFactoryScope scope) {
final SqmDeleteStatement sqm = (SqmDeleteStatement) scope.getSessionFactory()
final SqmDeleteStatement<?> sqm = (SqmDeleteStatement<?>) scope.getSessionFactory()
.getQueryEngine()
.getHqlTranslator()
.translate( "delete Customer where name = :n" );
@ -127,7 +127,7 @@ public class IdSelectionTests {
@Test
public void testJoinedSubclassRestrictedOnNonPrimaryRootTable(SessionFactoryScope scope) {
final SqmDeleteStatement sqm = (SqmDeleteStatement) scope.getSessionFactory()
final SqmDeleteStatement<?> sqm = (SqmDeleteStatement<?>) scope.getSessionFactory()
.getQueryEngine()
.getHqlTranslator()
.translate( "delete ForeignCustomer where name = :n" );
@ -152,7 +152,7 @@ public class IdSelectionTests {
@Test
public void testJoinedSubclassRestrictedOnPrimaryNonRootTable(SessionFactoryScope scope) {
final SqmDeleteStatement sqm = (SqmDeleteStatement) scope.getSessionFactory()
final SqmDeleteStatement<?> sqm = (SqmDeleteStatement<?>) scope.getSessionFactory()
.getQueryEngine()
.getHqlTranslator()
.translate( "delete ForeignCustomer where vat = :v" );

View File

@ -0,0 +1,163 @@
/*
* 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.orm.test.set;
import java.util.List;
import javax.persistence.Tuple;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.JpaCriteriaQuery;
import org.hibernate.query.criteria.JpaRoot;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.domain.gambit.EntityOfLists;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
*
* @author Christian Beikov
*/
@DomainModel( standardModels = StandardDomainModel.GAMBIT )
@ServiceRegistry
@SessionFactory
public class SetOperationJpaCriteriaTest {
@BeforeEach
public void createTestData(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
session.save( new EntityOfLists( 1, "first" ) );
session.save( new EntityOfLists( 2, "second" ) );
session.save( new EntityOfLists( 3, "third" ) );
}
);
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
session.createQuery( "delete from EntityOfLists" ).executeUpdate();
session.createQuery( "delete from SimpleEntity" ).executeUpdate();
}
);
}
@Test
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsUnion.class)
public void testUnionAll(SessionFactoryScope scope) {
scope.inSession(
session -> {
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
JpaCriteriaQuery<EntityOfLists> query1 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root1 = query1.from( EntityOfLists.class );
query1.where( cb.equal( root1.get( "id" ), 1 ) );
JpaCriteriaQuery<EntityOfLists> query2 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root2 = query2.from( EntityOfLists.class );
query2.where( cb.equal( root2.get( "id" ), 2 ) );
List<EntityOfLists> list = session.createQuery(
cb.unionAll( query1, query2 )
).list();
assertThat( list.size(), is( 2 ) );
}
);
}
@Test
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsUnion.class)
public void testUnionAllLimit(SessionFactoryScope scope) {
scope.inSession(
session -> {
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
JpaCriteriaQuery<EntityOfLists> query1 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root1 = query1.from( EntityOfLists.class );
query1.where( cb.equal( root1.get( "id" ), 1 ) );
JpaCriteriaQuery<EntityOfLists> query2 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root2 = query2.from( EntityOfLists.class );
query2.where( cb.equal( root2.get( "id" ), 2 ) );
List<EntityOfLists> list = session.createQuery(
cb.unionAll( query1, query2 )
.orderBy( cb.asc( cb.literal( 1 ) ) )
.fetch( 1 )
).list();
assertThat( list.size(), is( 1 ) );
}
);
}
@Test
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsUnion.class)
public void testUnionAllLimitSubquery(SessionFactoryScope scope) {
scope.inSession(
session -> {
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
JpaCriteriaQuery<EntityOfLists> query1 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root1 = query1.from( EntityOfLists.class );
query1.where( cb.equal( root1.get( "id" ), 1 ) );
JpaCriteriaQuery<EntityOfLists> query2 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root2 = query2.from( EntityOfLists.class );
query2.where( cb.equal( root2.get( "id" ), 2 ) );
List<EntityOfLists> list = session.createQuery(
cb.unionAll(
query1,
query2.orderBy( cb.asc( cb.literal( 1 ) ) )
.fetch( 1 )
)
).list();
assertThat( list.size(), is( 2 ) );
}
);
}
@Test
@RequiresDialectFeature(feature = DialectFeatureChecks.SupportsUnion.class)
public void testUnionAllLimitNested(SessionFactoryScope scope) {
scope.inSession(
session -> {
HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
JpaCriteriaQuery<EntityOfLists> query1 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root1 = query1.from( EntityOfLists.class );
query1.where( cb.equal( root1.get( "id" ), 1 ) );
JpaCriteriaQuery<EntityOfLists> query2 = cb.createQuery( EntityOfLists.class );
JpaRoot<EntityOfLists> root2 = query2.from( EntityOfLists.class );
query2.where( cb.equal( root2.get( "id" ), 2 ) );
List<EntityOfLists> list = session.createQuery(
cb.unionAll(
query1,
query2.orderBy( cb.asc( cb.literal( 1 ) ) )
.fetch( 1 )
).orderBy( cb.asc( cb.literal( 1 ) ) )
.fetch( 1 )
).list();
assertThat( list.size(), is( 1 ) );
}
);
}
}

View File

@ -77,13 +77,12 @@ public class SmokeTests {
String.class
);
final HqlQueryImplementor<String> hqlQuery = (HqlQueryImplementor<String>) query;
//noinspection unchecked
final SqmSelectStatement<String> sqmStatement = (SqmSelectStatement<String>) hqlQuery.getSqmStatement();
final StandardSqmTranslator<SelectStatement> sqmConverter = new StandardSqmTranslator<>(
sqmStatement,
hqlQuery.getQueryOptions(),
( (QuerySqmImpl) hqlQuery ).getDomainParameterXref(),
( (QuerySqmImpl<?>) hqlQuery ).getDomainParameterXref(),
query.getParameterBindings(),
session.getLoadQueryInfluencers(),
scope.getSessionFactory()
@ -138,13 +137,12 @@ public class SmokeTests {
session -> {
final QueryImplementor<Gender> query = session.createQuery( "select e.gender from SimpleEntity e", Gender.class );
final HqlQueryImplementor<Gender> hqlQuery = (HqlQueryImplementor<Gender>) query;
//noinspection unchecked
final SqmSelectStatement<Gender> sqmStatement = (SqmSelectStatement<Gender>) hqlQuery.getSqmStatement();
final StandardSqmTranslator<SelectStatement> sqmConverter = new StandardSqmTranslator<>(
sqmStatement,
hqlQuery.getQueryOptions(),
( (QuerySqmImpl) hqlQuery ).getDomainParameterXref(),
( (QuerySqmImpl<?>) hqlQuery ).getDomainParameterXref(),
query.getParameterBindings(),
session.getLoadQueryInfluencers(),
scope.getSessionFactory()

View File

@ -28,7 +28,7 @@ public class AbstractResultTests {
protected SelectStatement interpret(String hql, QueryParameterBindings parameterBindings, SessionFactoryImplementor sessionFactory) {
final QueryEngine queryEngine = sessionFactory.getQueryEngine();
final SqmSelectStatement sqm = (SqmSelectStatement) queryEngine.getHqlTranslator().translate( hql );
final SqmSelectStatement<?> sqm = (SqmSelectStatement<?>) queryEngine.getHqlTranslator().translate( hql );
final SqmTranslatorFactory sqmTranslatorFactory = queryEngine.getSqmTranslatorFactory();
final SqmTranslator<SelectStatement> sqmConverter = sqmTranslatorFactory.createSelectTranslator(

View File

@ -269,19 +269,19 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
// select clause
// control
Query query = session.createQuery( "select a.class from Animal a where a.class = Dog" );
Query<?> query = session.createQuery( "select a.class from Animal a where a.class = Dog" );
query.list();
SqmSelectStatement sqmStatement = (SqmSelectStatement) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
SqmSelectStatement<?> sqmStatement = (SqmSelectStatement<?>) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
List<SqmSelection> selections = sqmStatement.getQuerySpec().getSelectClause().getSelections();
assertEquals( 1, selections.size() );
SqmSelection typeSelection = selections.get( 0 );
SqmSelection<?> typeSelection = selections.get( 0 );
// always integer for joined
assertEquals( Integer.class, typeSelection.getNodeJavaTypeDescriptor().getJavaType() );
// test
query = session.createQuery( "select type(a) from Animal a where type(a) = Dog" );
query.list();
sqmStatement = (SqmSelectStatement) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
sqmStatement = (SqmSelectStatement<?>) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
selections = sqmStatement.getQuerySpec().getSelectClause().getSelections();
assertEquals( 1, selections.size() );
typeSelection = selections.get( 0 );
@ -1540,11 +1540,11 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
public void testComponentQueries() {
inTransaction(
session -> {
final QueryImplementor query = session.createQuery( "select h.name from Human h" );
final SqmSelectStatement sqmStatement = (SqmSelectStatement) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
final QueryImplementor<?> query = session.createQuery( "select h.name from Human h" );
final SqmSelectStatement<?> sqmStatement = (SqmSelectStatement<?>) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
assertEquals( 1, sqmStatement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmSelection selection = sqmStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
final SqmExpressable selectionType = selection.getSelectableNode().getNodeType();
final SqmSelection<?> selection = sqmStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
final SqmExpressable<?> selectionType = selection.getSelectableNode().getNodeType();
assertThat( selectionType, CoreMatchers.instanceOf( EmbeddableDomainType.class ) );
assertEquals( Name.class, selection.getNodeJavaTypeDescriptor().getJavaType() );
@ -1824,10 +1824,10 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
inSession(
session -> {
final Query query = session.createQuery( "from Animal a inner join fetch a.mother" );
final SqmSelectStatement sqmStatement = (SqmSelectStatement) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
final SqmSelectStatement<?> sqmStatement = (SqmSelectStatement<?>) query.unwrap( QuerySqmImpl.class ).getSqmStatement();
assertEquals( 1, sqmStatement.getQuerySpec().getSelectClause().getSelections().size() );
final SqmSelection selection = sqmStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
final SqmExpressable selectionType = selection.getSelectableNode().getNodeType();
final SqmSelection<?> selection = sqmStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
final SqmExpressable<?> selectionType = selection.getSelectableNode().getNodeType();
assertThat( selectionType, instanceOf( EntityDomainType.class ) );
assertThat( selectionType.getExpressableJavaTypeDescriptor().getJavaType(), equalTo( Animal.class ) );
assertThat( selection.getAlias(), is( "a" ) );
@ -2148,15 +2148,15 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
}
private static void verifyAnimalZooSelection(Query q) {
final SqmSelectStatement sqmStatement = (SqmSelectStatement) q.unwrap( QuerySqmImpl.class ).getSqmStatement();
final SqmSelection sqmSelection = sqmStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
final SqmSelectStatement<?> sqmStatement = (SqmSelectStatement<?>) q.unwrap( QuerySqmImpl.class ).getSqmStatement();
final SqmSelection<?> sqmSelection = sqmStatement.getQuerySpec().getSelectClause().getSelections().get( 0 );
assertThat( sqmSelection.getSelectableNode(), instanceOf( SqmPath.class ) );
final SqmPath selectedPath = (SqmPath) sqmSelection.getSelectableNode();
final SqmPath<?> selectedPath = (SqmPath<?>) sqmSelection.getSelectableNode();
assertThat( selectedPath.getReferencedPathSource(), instanceOf( SingularPersistentAttribute.class ) );
final SingularPersistentAttribute selectedAttr = (SingularPersistentAttribute) selectedPath.getReferencedPathSource();
assertThat( selectedAttr.getName(), is( "zoo" ) );
assertThat( selectedAttr.getType(), instanceOf( EntityDomainType.class ) );
final EntityDomainType zooType = (EntityDomainType) selectedAttr.getType();
final EntityDomainType<?> zooType = (EntityDomainType<?>) selectedAttr.getType();
assertThat( zooType.getHibernateEntityName(), is( Zoo.class.getName() ) );
}
@ -2596,15 +2596,15 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase {
a.setDescription("an animal");
s.persist(a);
Query q = s.createQuery( "select a.bodyWeight as abw, a.description from Animal a" );
SqmSelectStatement sqmStatement = (SqmSelectStatement) q.unwrap( QuerySqmImpl.class ).getSqmStatement();
Query<?> q = s.createQuery( "select a.bodyWeight as abw, a.description from Animal a" );
SqmSelectStatement<?> sqmStatement = (SqmSelectStatement<?>) q.unwrap( QuerySqmImpl.class ).getSqmStatement();
List<SqmSelection> selections = sqmStatement.getQuerySpec().getSelectClause().getSelections();
assertThat( selections.size(), is( 2 ) );
assertThat( selections.get( 0 ).getAlias(), is( "abw" ) );
assertThat( selections.get( 1 ).getAlias(), nullValue() );
q = s.createQuery("select count(*), avg(a.bodyWeight) as avg from Animal a");
sqmStatement = (SqmSelectStatement) q.unwrap( QuerySqmImpl.class ).getSqmStatement();
sqmStatement = (SqmSelectStatement<?>) q.unwrap( QuerySqmImpl.class ).getSqmStatement();
selections = sqmStatement.getQuerySpec().getSelectClause().getSelections();
assertThat( selections.size(), is( 2 ) );
assertThat( selections.get( 0 ), nullValue() );