Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.hibernate.query.IllegalMutationQueryException;
import org.hibernate.query.MutationQuery;
import org.hibernate.query.restriction.Restriction;
import org.hibernate.query.spi.HqlInterpretation;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmQuerySource;
Expand All @@ -43,7 +42,7 @@
import static org.hibernate.query.sqm.tree.SqmCopyContext.noParamCopyContext;

/**
* Standard implementation of MutationSpecification
* Standard implementation of {@link MutationSpecification}.
*
* @author Steve Ebersole
*/
Expand Down Expand Up @@ -95,10 +94,9 @@ public TypedQueryReference<Void> reference() {
@Override
public MutationSpecification<T> restrict(Restriction<? super T> restriction) {
specifications.add( (sqmStatement, mutationTargetRoot) -> {
final SqmPredicate sqmPredicate = (SqmPredicate) restriction.toPredicate(
mutationTargetRoot,
sqmStatement.nodeBuilder()
);
final var sqmPredicate = (SqmPredicate)
restriction.toPredicate( mutationTargetRoot,
sqmStatement.nodeBuilder() );
sqmStatement.applyPredicate( sqmPredicate );
} );
return this;
Expand All @@ -123,7 +121,7 @@ public MutationQuery createQuery(StatelessSession session) {

public MutationQuery createQuery(SharedSessionContract session) {
final var sessionImpl = session.unwrap(SharedSessionContractImplementor.class);
final SqmDeleteOrUpdateStatement<T> sqmStatement = build( sessionImpl.getFactory().getQueryEngine() );
final var sqmStatement = build( sessionImpl.getFactory().getQueryEngine() );
return new SqmQueryImpl<>( sqmStatement, true, null, sessionImpl );
}

Expand Down Expand Up @@ -153,13 +151,13 @@ public MutationQuery createQuery(EntityManager entityManager) {

@Override
public CommonAbstractCriteria buildCriteria(CriteriaBuilder builder) {
final NodeBuilder nodeBuilder = (NodeBuilder) builder;
final var nodeBuilder = (NodeBuilder) builder;
return build( nodeBuilder.getQueryEngine() );
}

@Override
public MutationSpecification<T> validate(CriteriaBuilder builder) {
final NodeBuilder nodeBuilder = (NodeBuilder) builder;
final var nodeBuilder = (NodeBuilder) builder;
final var statement = build( nodeBuilder.getQueryEngine() );
( (AbstractSqmDmlStatement<?>) statement ).validate( hql );
return this;
Expand All @@ -170,36 +168,36 @@ public MutationSpecification<T> validate(CriteriaBuilder builder) {
* and produce the corresponding SQM tree.
*/
private static <T> SqmDeleteOrUpdateStatement<T> resolveSqmTree(String hql, QueryEngine queryEngine) {
final HqlInterpretation<T> hqlInterpretation =
final var hqlInterpretation =
queryEngine.getInterpretationCache()
.resolveHqlInterpretation( hql, null, queryEngine.getHqlTranslator() );
.<T>resolveHqlInterpretation( hql, null, queryEngine.getHqlTranslator() );

if ( !SqmUtil.isRestrictedMutation( hqlInterpretation.getSqmStatement() ) ) {
throw new IllegalMutationQueryException( "Expecting a delete or update query, but found '" + hql + "'", hql);
}

// NOTE: this copy is to isolate the actual AST tree from the
// one stored in the interpretation cache
return (SqmDeleteOrUpdateStatement<T>) hqlInterpretation
.getSqmStatement()
.copy( noParamCopyContext( SqmQuerySource.CRITERIA ) );
return (SqmDeleteOrUpdateStatement<T>)
hqlInterpretation.getSqmStatement()
.copy( noParamCopyContext( SqmQuerySource.CRITERIA ) );
}

/**
* Used during construction. Mainly used to group extracting and
* Used during construction. Mainly used to group extracting and
* validating the root.
*/
private static <T> SqmRoot<T> resolveSqmRoot(
SqmDeleteOrUpdateStatement<T> sqmStatement,
Class<T> mutationTarget) {
final SqmRoot<T> mutationTargetRoot = sqmStatement.getTarget();
if ( mutationTargetRoot.getJavaType() != null
&& !mutationTarget.isAssignableFrom( mutationTargetRoot.getJavaType() ) ) {
final var mutationTargetRoot = sqmStatement.getTarget();
final var javaType = mutationTargetRoot.getJavaType();
if ( javaType != null && !mutationTarget.isAssignableFrom( javaType ) ) {
throw new IllegalArgumentException(
String.format(
Locale.ROOT,
"Mutation target types do not match : %s / %s",
mutationTargetRoot.getJavaType().getName(),
javaType.getName(),
mutationTarget.getName()
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,29 @@
import org.hibernate.query.specification.SelectionSpecification;
import org.hibernate.query.restriction.Path;
import org.hibernate.query.restriction.Restriction;
import org.hibernate.query.spi.HqlInterpretation;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmQuerySource;
import org.hibernate.query.sqm.internal.SqmSelectionQueryImpl;
import org.hibernate.query.sqm.internal.SqmUtil;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
import org.hibernate.query.sqm.tree.select.SqmSelectClause;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.select.SqmSelection;
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
import org.hibernate.type.descriptor.java.JavaType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty;
import static org.hibernate.query.sqm.internal.SqmUtil.validateCriteriaQuery;
import static org.hibernate.query.sqm.tree.SqmCopyContext.noParamCopyContext;

/**
* Standard implementation of SelectionSpecification
* Standard implementation of {@link SelectionSpecification}.
*
* @author Steve Ebersole
*/
Expand Down Expand Up @@ -99,7 +93,7 @@ public TypedQueryReference<T> reference() {
@Override
public SelectionSpecification<T> restrict(Restriction<? super T> restriction) {
specifications.add( (sqmStatement, root) -> {
final SqmPredicate sqmPredicate = SqmUtil.restriction( sqmStatement, resultType, restriction );
final var sqmPredicate = SqmUtil.restriction( sqmStatement, resultType, restriction );
sqmStatement.getQuerySpec().applyPredicate( sqmPredicate );
} );
return this;
Expand Down Expand Up @@ -145,7 +139,7 @@ public final SelectionSpecification<T> resort(List<? extends Order<? super T>> o
}

private static <T> void addOrder(Order<? super T> order, SqmSelectStatement<T> sqmStatement) {
final SqmSortSpecification sortSpecification = SqmUtil.sortSpecification( sqmStatement, order );
final var sortSpecification = SqmUtil.sortSpecification( sqmStatement, order );
final var querySpec = sqmStatement.getQuerySpec();
if ( querySpec.getOrderByClause() == null ) {
querySpec.setOrderByClause( new SqmOrderByClause() );
Expand All @@ -165,7 +159,7 @@ public SelectionQuery<T> createQuery(StatelessSession session) {

public SelectionQuery<T> createQuery(SharedSessionContract session) {
final var sessionImpl = session.unwrap(SharedSessionContractImplementor.class);
final SqmSelectStatement<T> sqmStatement = build( sessionImpl.getFactory().getQueryEngine() );
final var sqmStatement = build( sessionImpl.getFactory().getQueryEngine() );
return new SqmSelectionQueryImpl<>( sqmStatement, true, resultType, sessionImpl );
}

Expand Down Expand Up @@ -199,13 +193,13 @@ public SelectionQuery<T> createQuery(EntityManager entityManager) {

@Override
public CriteriaQuery<T> buildCriteria(CriteriaBuilder builder) {
final NodeBuilder nodeBuilder = (NodeBuilder) builder;
final var nodeBuilder = (NodeBuilder) builder;
return build( nodeBuilder.getQueryEngine() );
}

@Override
public SelectionSpecification<T> validate(CriteriaBuilder builder) {
final NodeBuilder nodeBuilder = (NodeBuilder) builder;
final var nodeBuilder = (NodeBuilder) builder;
final var statement = build( nodeBuilder.getQueryEngine() );
final var queryPart = statement.getQueryPart();
// For criteria queries, we have to validate the fetch structure here
Expand All @@ -220,7 +214,7 @@ public SelectionSpecification<T> validate(CriteriaBuilder builder) {
* and produce the corresponding SQM tree.
*/
private static <T> SqmSelectStatement<T> resolveSqmTree(String hql, Class<T> resultType, QueryEngine queryEngine) {
final HqlInterpretation<T> hqlInterpretation =
final var hqlInterpretation =
queryEngine.getInterpretationCache()
.resolveHqlInterpretation( hql, resultType, queryEngine.getHqlTranslator() );

Expand All @@ -231,25 +225,25 @@ private static <T> SqmSelectStatement<T> resolveSqmTree(String hql, Class<T> res

// NOTE: this copy is to isolate the actual AST tree from the
// one stored in the interpretation cache
return (SqmSelectStatement<T>) hqlInterpretation
.getSqmStatement()
.copy( noParamCopyContext( SqmQuerySource.CRITERIA ) );
return (SqmSelectStatement<T>)
hqlInterpretation.getSqmStatement()
.copy( noParamCopyContext( SqmQuerySource.CRITERIA ) );
}

/**
* Used during construction. Mainly used to group extracting and
* Used during construction. Mainly used to group extracting and
* validating the root.
*/
private SqmRoot<T> extractRoot(SqmSelectStatement<T> sqmStatement, Class<T> resultType, String hql) {
final Set<SqmRoot<?>> sqmRoots = sqmStatement.getQuerySpec().getRoots();
final var sqmRoots = sqmStatement.getQuerySpec().getRoots();
if ( sqmRoots.isEmpty() ) {
throw new QueryException( "Query did not define any roots", hql );
}
if ( sqmRoots.size() > 1 ) {
throw new QueryException( "Query defined multiple roots", hql );
}

final SqmRoot<?> sqmRoot = sqmRoots.iterator().next();
final var sqmRoot = sqmRoots.iterator().next();
validateRoot( sqmRoot, resultType, hql );
// for later, to support select lists
//validateResultType( sqmStatement, sqmRoot, resultType, hql );
Expand All @@ -259,14 +253,15 @@ private SqmRoot<T> extractRoot(SqmSelectStatement<T> sqmStatement, Class<T> resu
}

private void validateRoot(SqmRoot<?> sqmRoot, Class<T> resultType, String hql) {
if ( sqmRoot.getJavaType() != null
&& !Map.class.isAssignableFrom( sqmRoot.getJavaType() )
&& !resultType.isAssignableFrom( sqmRoot.getJavaType() ) ) {
final var javaType = sqmRoot.getJavaType();
if ( javaType != null
&& !Map.class.isAssignableFrom( javaType )
&& !resultType.isAssignableFrom( javaType ) ) {
throw new QueryException(
String.format(
Locale.ROOT,
"Query root [%s] and result type [%s] are not compatible",
sqmRoot.getJavaType().getName(),
javaType.getName(),
resultType.getName()
),
hql
Expand Down Expand Up @@ -297,8 +292,8 @@ private void validateResultType(
}
}

final SqmSelectClause sqmSelectClause = sqmStatement.getQuerySpec().getSelectClause();
final List<SqmSelection<?>> sqmSelections = sqmSelectClause.getSelections();
final var sqmSelectClause = sqmStatement.getQuerySpec().getSelectClause();
final var sqmSelections = sqmSelectClause.getSelections();
if ( isEmpty( sqmSelections ) ) {
// implicit select clause, verify that resultType matches the root type
if ( resultType.isAssignableFrom( rootJavaType ) ) {
Expand Down
Loading