HHH-17377 - Migrate to JPA 3.2

https://hibernate.atlassian.net/browse/HHH-17377

Fixed SQM/JPA Criteria compilation errors.  Just Graph left
This commit is contained in:
Steve Ebersole 2023-11-01 17:37:38 -05:00
parent 3c6e5c45c4
commit 1e110584f1
72 changed files with 1167 additions and 620 deletions

View File

@ -1 +1 @@
hibernateVersion=6.6.1-SNAPSHOT
hibernateVersion=7.0.0-SNAPSHOT

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.boot.model.internal;
import jakarta.persistence.CheckConstraint;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.MapsId;
import jakarta.persistence.PrimaryKeyJoinColumn;
@ -368,6 +369,21 @@ class ColumnsBuilder {
return "";
}
@Override
public String options() {
return column.options();
}
@Override
public CheckConstraint[] check() {
return new CheckConstraint[0];
}
@Override
public String comment() {
return "";
}
@Override
public ForeignKey foreignKey() {
return column.foreignKey();

View File

@ -500,7 +500,7 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
}
@Override
public <X> EmbeddableDomainType<X> embeddable(String embeddableName) {
public EmbeddableDomainType<?> embeddable(String embeddableName) {
return jpaMetamodel.embeddable( embeddableName );
}

View File

@ -34,8 +34,8 @@ public interface JpaCollectionJoin<O, T> extends JpaPluralJoin<O, Collection<T>,
JpaCollectionJoin<O, T> on(Predicate... restrictions);
@Override
<S extends T> JpaCollectionJoin<O, S> treatAs(Class<S> treatAsType);
<S extends T> JpaTreatedJoin<O,T, S> treatAs(Class<S> treatAsType);
@Override
<S extends T> JpaCollectionJoin<O, S> treatAs(EntityDomainType<S> treatAsType);
<S extends T> JpaTreatedJoin<O,T, S> treatAs(EntityDomainType<S> treatAsType);
}

View File

@ -12,5 +12,5 @@ import org.hibernate.Incubating;
* @author Marco Belladelli
*/
@Incubating
public interface JpaCrossJoin<T> extends JpaFrom<T, T> {
public interface JpaCrossJoin<T> extends JpaFrom<T,T> {
}

View File

@ -15,7 +15,7 @@ import jakarta.persistence.criteria.Predicate;
* @author Christian Beikov
*/
@Incubating
public interface JpaDerivedJoin<T> extends JpaDerivedFrom<T>, JpaJoinedFrom<T,T> {
public interface JpaDerivedJoin<T> extends JpaDerivedFrom<T>, JpaJoin<T,T> {
/**
* Specifies whether the subquery part can access previous from node aliases.
* Normally, subqueries in the from clause are unable to access other from nodes,

View File

@ -7,26 +7,18 @@
package org.hibernate.query.criteria;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
import org.hibernate.query.sqm.tree.domain.SqmTreatedEntityJoin;
/**
* @author Steve Ebersole
*/
public interface JpaEntityJoin<L,R> extends JpaJoinedFrom<L,R> {
public interface JpaEntityJoin<L,R> extends JpaJoin<L,R> {
@Override
EntityDomainType<R> getModel();
@Override
JpaEntityJoin<L,R> on(JpaExpression<Boolean> restriction);
<S extends R> SqmTreatedEntityJoin<L,R,S> treatAs(Class<S> treatAsType);
@Override
JpaEntityJoin<L,R> on(Expression<Boolean> restriction);
@Override
JpaEntityJoin<L,R> on(JpaPredicate... restrictions);
@Override
JpaEntityJoin<L,R> on(Predicate... restrictions);
<S extends R> SqmTreatedEntityJoin<L,R,S> treatAs(EntityDomainType<S> treatAsType);
}

View File

@ -11,7 +11,6 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.tree.SqmJoinType;
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Subquery;
import jakarta.persistence.metamodel.CollectionAttribute;
@ -68,10 +67,10 @@ public interface JpaFrom<O,T> extends JpaPath<T>, JpaFetchParent<O,T>, From<O,T>
<X> JpaDerivedJoin<X> join(Subquery<X> subquery, SqmJoinType joinType, boolean lateral);
@Incubating
<X> JpaJoinedFrom<?, X> join(JpaCteCriteria<X> cte);
<X> JpaJoin<?, X> join(JpaCteCriteria<X> cte);
@Incubating
<X> JpaJoinedFrom<?, X> join(JpaCteCriteria<X> cte, SqmJoinType joinType);
<X> JpaJoin<?, X> join(JpaCteCriteria<X> cte, SqmJoinType joinType);
@Incubating
<X> JpaCrossJoin<X> crossJoin(Class<X> entityJavaType);
@ -142,8 +141,8 @@ public interface JpaFrom<O,T> extends JpaPath<T>, JpaFetchParent<O,T>, From<O,T>
<X, K, V> JpaMapJoin<X, K, V> joinMap(String attributeName, JoinType jt);
@Override
<S extends T> JpaFrom<O,S> treatAs(Class<S> treatJavaType);
<S extends T> JpaTreatedFrom<O,T,S> treatAs(Class<S> treatJavaType);
@Override
<S extends T> JpaFrom<O,S> treatAs(EntityDomainType<S> treatJavaType);
<S extends T> JpaTreatedFrom<O,T,S> treatAs(EntityDomainType<S> treatJavaType);
}

View File

@ -35,8 +35,8 @@ public interface JpaJoin<L, R> extends JpaFrom<L,R>, Join<L,R> {
JpaJoin<L, R> on(Predicate... restrictions);
@Override
<S extends R> JpaJoin<L, S> treatAs(Class<S> treatAsType);
<S extends R> JpaTreatedJoin<L,R,S> treatAs(Class<S> treatAsType);
@Override
<S extends R> JpaJoin<L, S> treatAs(EntityDomainType<S> treatAsType);
<S extends R> JpaTreatedJoin<L,R,S> treatAs(EntityDomainType<S> treatAsType);
}

View File

@ -1,34 +0,0 @@
/*
* 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 jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* Exists within the hierarchy mainly to support "entity joins".
*
* @see JpaEntityJoin
* @see org.hibernate.query.sqm.tree.from.SqmEntityJoin
* @see JpaDerivedJoin
* @see org.hibernate.query.sqm.tree.from.SqmDerivedJoin
*
* @author Steve Ebersole
*/
public interface JpaJoinedFrom<L, R> extends JpaFrom<L,R>, JpaJoin<L,R> {
JpaJoinedFrom<L, R> on(JpaExpression<Boolean> restriction);
JpaJoinedFrom<L, R> on(Expression<Boolean> restriction);
JpaJoinedFrom<L, R> on(JpaPredicate... restrictions);
JpaJoinedFrom<L, R> on(Predicate... restrictions);
JpaPredicate getOn();
}

View File

@ -33,8 +33,8 @@ public interface JpaListJoin<O, T> extends JpaPluralJoin<O, List<T>, T>, ListJoi
JpaListJoin<O, T> on(Predicate... restrictions);
@Override
<S extends T> JpaListJoin<O, S> treatAs(Class<S> treatAsType);
<S extends T> JpaTreatedJoin<O,T, S> treatAs(Class<S> treatAsType);
@Override
<S extends T> JpaListJoin<O, S> treatAs(EntityDomainType<S> treatAsType);
<S extends T> JpaTreatedJoin<O,T, S> treatAs(EntityDomainType<S> treatAsType);
}

View File

@ -9,7 +9,6 @@ package org.hibernate.query.criteria;
import java.util.Map;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.PathException;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.MapJoin;
@ -34,8 +33,8 @@ public interface JpaMapJoin<O,K,V> extends JpaPluralJoin<O, Map<K, V>, V>, MapJo
JpaMapJoin<O, K, V> on(Predicate... restrictions);
@Override
<S extends V> JpaMapJoin<O, K, S> treatAs(Class<S> treatAsType);
<S extends V> JpaTreatedJoin<O, V, S> treatAs(Class<S> treatAsType);
@Override
<S extends V> JpaMapJoin<O, K, S> treatAs(EntityDomainType<S> treatJavaType);
<S extends V> JpaTreatedJoin<O, V, S> treatAs(EntityDomainType<S> treatJavaType);
}

View File

@ -16,6 +16,7 @@ import jakarta.persistence.metamodel.PluralAttribute;
import jakarta.persistence.metamodel.SingularAttribute;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.spi.NavigablePath;
/**
@ -37,7 +38,7 @@ public interface JpaPath<T> extends JpaExpression<T>, Path<T> {
/**
* Support for JPA's explicit (TREAT) down-casting.
*/
<S extends T> JpaPath<S> treatAs(Class<S> treatJavaType);
<S extends T> JpaTreatedPath<T,S> treatAs(Class<S> treatJavaType);
/**
* Support for JPA's explicit (TREAT) down-casting.

View File

@ -35,8 +35,8 @@ public interface JpaPluralJoin<O, C, E> extends JpaJoin<O, E>, PluralJoin<O, C,
JpaPluralJoin<O, ? extends C, E> on(Predicate... restrictions);
@Override
<S extends E> JpaPluralJoin<O, ?, S> treatAs(Class<S> treatAsType);
<S extends E> JpaTreatedJoin<O, E, S> treatAs(Class<S> treatAsType);
@Override
<S extends E> JpaPluralJoin<O, ?, S> treatAs(EntityDomainType<S> treatAsType);
<S extends E> JpaTreatedJoin<O, E, S> treatAs(EntityDomainType<S> treatAsType);
}

View File

@ -33,8 +33,8 @@ public interface JpaSetJoin<O, T> extends JpaPluralJoin<O, Set<T>, T>, SetJoin<O
JpaSetJoin<O, T> on(Predicate... restrictions);
@Override
<S extends T> JpaSetJoin<O, S> treatAs(Class<S> treatAsType);
<S extends T> JpaTreatedJoin<O,T,S> treatAs(Class<S> treatAsType);
@Override
<S extends T> JpaSetJoin<O, S> treatAs(EntityDomainType<S> treatAsType);
<S extends T> JpaTreatedJoin<O,T,S> treatAs(EntityDomainType<S> treatAsType);
}

View File

@ -0,0 +1,20 @@
/*
* 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 org.hibernate.metamodel.model.domain.EntityDomainType;
/**
* @author Steve Ebersole
*/
public interface JpaTreatedFrom<L,R,R1 extends R> extends JpaTreatedPath<R,R1>, JpaFrom<L,R1> {
@Override
<S extends R1> JpaTreatedFrom<L, R1, S> treatAs(Class<S> treatJavaType);
@Override
<S extends R1> JpaTreatedFrom<L, R1, S> treatAs(EntityDomainType<S> treatJavaType);
}

View File

@ -0,0 +1,20 @@
/*
* 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 org.hibernate.metamodel.model.domain.EntityDomainType;
/**
* @author Steve Ebersole
*/
public interface JpaTreatedJoin<L,R,R1 extends R> extends JpaTreatedFrom<L,R,R1>, JpaJoin<L,R1> {
@Override
<S extends R1> JpaTreatedJoin<L, R1, S> treatAs(Class<S> treatJavaType);
@Override
<S extends R1> JpaTreatedJoin<L, R1, S> treatAs(EntityDomainType<S> treatJavaType);
}

View File

@ -0,0 +1,16 @@
/*
* 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 org.hibernate.metamodel.model.domain.ManagedDomainType;
/**
* @author Steve Ebersole
*/
public interface JpaTreatedPath<T,S extends T> extends JpaPath<S> {
ManagedDomainType<S> getTreatTarget();
}

View File

@ -349,7 +349,8 @@ public class QualifiedJoinPathConsumer implements DotIdentifierConsumer {
if ( joinedEntityType == null ) {
final SqmCteStatement<?> cteStatement = creationState.findCteStatement( fullPath );
if ( cteStatement != null ) {
join = new SqmCteJoin<>( cteStatement, alias, joinType, sqmRoot );
//noinspection rawtypes,unchecked
join = new SqmCteJoin( cteStatement, alias, joinType, sqmRoot );
creationState.getCurrentProcessingState().getPathRegistry().register( join );
return;
}

View File

@ -16,7 +16,7 @@ import org.hibernate.query.sqm.tree.SqmQuery;
import org.hibernate.query.sqm.tree.domain.SqmCorrelation;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmFromClause;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.from.SqmJoin;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.select.SqmQuerySpec;
import org.hibernate.query.sqm.tree.select.SqmSelectQuery;
@ -29,10 +29,10 @@ import org.hibernate.query.sqm.tree.select.SqmSubQuery;
* @author Steve Ebersole
*/
public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsumer {
private final SqmQualifiedJoin<?, ?> sqmJoin;
private final SqmJoin<?, ?> sqmJoin;
public QualifiedJoinPredicatePathConsumer(
SqmQualifiedJoin<?, ?> sqmJoin,
SqmJoin<?, ?> sqmJoin,
SqmCreationState creationState) {
super( creationState );
this.sqmJoin = sqmJoin;

View File

@ -170,7 +170,6 @@ 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.SqmJoin;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.insert.SqmConflictClause;
import org.hibernate.query.sqm.tree.insert.SqmConflictUpdateAction;
@ -227,7 +226,6 @@ import org.hibernate.type.spi.TypeConfiguration;
import org.jboss.logging.Logger;
import jakarta.persistence.criteria.Nulls;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.Bindable;
import jakarta.persistence.metamodel.SingularAttribute;
@ -2223,7 +2221,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
dotIdentifierConsumerStack.push( new QualifiedJoinPathConsumer( sqmRoot, joinType, fetch, alias, this ) );
try {
final SqmQualifiedJoin<X, ?> join = getJoin( sqmRoot, joinType, qualifiedJoinTargetContext, alias, fetch );
final SqmJoin<X, ?> join = getJoin( sqmRoot, joinType, qualifiedJoinTargetContext, alias, fetch );
final HqlParser.JoinRestrictionContext joinRestrictionContext = parserJoin.joinRestriction();
if ( join instanceof SqmEntityJoin<?,?> || join instanceof SqmDerivedJoin<?> || join instanceof SqmCteJoin<?> ) {
sqmRoot.addSqmJoin( join );
@ -2271,7 +2269,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
}
@SuppressWarnings("unchecked")
private <X> SqmQualifiedJoin<X, ?> getJoin(
private <X> SqmJoin<X, ?> getJoin(
SqmRoot<X> sqmRoot,
SqmJoinType joinType,
HqlParser.JoinTargetContext joinTargetContext,
@ -2279,7 +2277,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
boolean fetch) {
if ( joinTargetContext instanceof HqlParser.JoinPathContext ) {
final HqlParser.JoinPathContext joinPathContext = (HqlParser.JoinPathContext) joinTargetContext;
return (SqmQualifiedJoin<X, ?>) joinPathContext.path().accept( this );
return (SqmJoin<X, ?>) joinPathContext.path().accept( this );
}
else if ( joinTargetContext instanceof HqlParser.JoinSubqueryContext ) {
if ( fetch ) {
@ -2298,7 +2296,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
final DotIdentifierConsumer identifierConsumer = dotIdentifierConsumerStack.pop();
final SqmSubQuery<X> subQuery = (SqmSubQuery<X>) joinSubqueryContext.subquery().accept( this );
dotIdentifierConsumerStack.push( identifierConsumer );
final SqmQualifiedJoin<X, ?> join = new SqmDerivedJoin<>( subQuery, alias, joinType, lateral, sqmRoot );
final SqmJoin<X, ?> join = new SqmDerivedJoin<>( subQuery, alias, joinType, lateral, sqmRoot );
processingStateStack.getCurrent().getPathRegistry().register( join );
return join;
}

View File

@ -16,6 +16,7 @@ import java.util.function.Function;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.spi.JpaMetamodelImplementor;
import org.hibernate.query.criteria.JpaCrossJoin;
import org.hibernate.query.SemanticException;
import org.hibernate.query.hql.HqlLogging;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
@ -238,8 +239,8 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
else if ( parentRegistered instanceof Join<?, ?> ) {
correlated = selectQuery.correlate( (Join<?, ?>) parentRegistered );
}
else if ( parentRegistered instanceof SqmCrossJoin<?> ) {
correlated = selectQuery.correlate( (SqmCrossJoin<?>) parentRegistered );
else if ( parentRegistered instanceof SqmCrossJoin ) {
correlated = selectQuery.correlate( (JpaCrossJoin) parentRegistered );
}
else if ( parentRegistered instanceof SqmEntityJoin<?,?> ) {
correlated = selectQuery.correlate( (SqmEntityJoin<?,?>) parentRegistered );

View File

@ -102,6 +102,8 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmSetJoin;
import org.hibernate.query.sqm.tree.domain.SqmSingularJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
import org.hibernate.query.sqm.tree.domain.SqmTreatedSingularJoin;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
@ -541,7 +543,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public <X, T extends X> SqmRoot<T> treat(Root<X> root, Class<T> type) {
return ( (SqmRoot<X>) root ).treatAs( type );
//noinspection unchecked
return (SqmTreatedRoot<X,T>) ( (SqmRoot<X>) root ).treatAs( type );
}
@Override
@ -582,7 +585,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
@Override
public <X, T, V extends T> SqmSingularJoin<X, V> treat(Join<X, T> join, Class<V> type) {
return ( (SqmSingularJoin<X, T>) join ).treatAs( type );
//noinspection unchecked
return (SqmTreatedSingularJoin<X,T,V>) ( (SqmSingularJoin<X, T>) join ).treatAs( type );
}
@Override

View File

@ -79,7 +79,7 @@ import org.hibernate.query.sqm.tree.from.SqmDerivedJoin;
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.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.from.SqmJoin;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.insert.SqmConflictClause;
import org.hibernate.query.sqm.tree.insert.SqmConflictUpdateAction;
@ -603,7 +603,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
private boolean inJoinPredicate;
private void processJoinPredicate(SqmQualifiedJoin<?, ?> joinedFromElement) {
private void processJoinPredicate(SqmJoin<?, ?> joinedFromElement) {
if ( joinedFromElement.getJoinPredicate() != null ) {
boolean oldInJoinPredicate = inJoinPredicate;
inJoinPredicate = true;

View File

@ -72,7 +72,6 @@ import org.hibernate.query.sqm.tree.expression.SqmTuple;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmJoin;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
@ -220,16 +219,11 @@ public class SqmUtil {
* or one that has an explicit on clause predicate.
*/
public static boolean isFkOptimizationAllowed(SqmPath<?> sqmPath) {
if ( sqmPath instanceof SqmJoin<?, ?> ) {
final SqmJoin<?, ?> sqmJoin = (SqmJoin<?, ?>) sqmPath;
switch ( sqmJoin.getSqmJoinType() ) {
case INNER:
case LEFT:
return !( sqmJoin instanceof SqmQualifiedJoin<?, ?>)
|| ( (SqmQualifiedJoin<?, ?>) sqmJoin ).getJoinPredicate() == null;
default:
return false;
}
if ( sqmPath instanceof SqmJoin<?, ?> sqmJoin ) {
return switch ( sqmJoin.getSqmJoinType() ) {
case INNER, LEFT -> sqmJoin.getJoinPredicate() == null;
default -> false;
};
}
return false;
}

View File

@ -33,6 +33,7 @@ import org.hibernate.query.sqm.tree.domain.SqmMapEntryReference;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPluralPartJoin;
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedFrom;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.query.sqm.tree.expression.AsWrapperSqmExpression;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
@ -299,7 +300,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
consumeExplicitJoin( sqmJoin, true );
}
);
final List<SqmFrom<?, ?>> sqmTreats = sqmFrom.getSqmTreats();
final List<SqmTreatedFrom<?,?,?>> sqmTreats = sqmFrom.getSqmTreats();
if ( !sqmTreats.isEmpty() ) {
for ( SqmFrom<?, ?> sqmTreat : sqmTreats ) {
consumeTreat( sqmTreat );

View File

@ -11,12 +11,11 @@ import java.util.List;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.predicate.SqmJunctionPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.sql.ast.tree.predicate.Junction;
import jakarta.persistence.criteria.Predicate;
@ -89,6 +88,30 @@ public class SqmCreationHelper {
return combined;
}
public static SqmPredicate combinePredicates(SqmPredicate baseRestriction, JpaPredicate... incomingRestrictions) {
if ( CollectionHelper.isEmpty( incomingRestrictions ) ) {
return baseRestriction;
}
SqmPredicate combined = combinePredicates( null, baseRestriction );
for ( int i = 0; i < incomingRestrictions.length; i++ ) {
combined = combinePredicates( combined, incomingRestrictions[i] );
}
return combined;
}
public static SqmPredicate combinePredicates(SqmPredicate baseRestriction, Predicate... incomingRestrictions) {
if ( CollectionHelper.isEmpty( incomingRestrictions ) ) {
return baseRestriction;
}
SqmPredicate combined = combinePredicates( null, baseRestriction );
for ( int i = 0; i < incomingRestrictions.length; i++ ) {
combined = combinePredicates( combined, incomingRestrictions[i] );
}
return combined;
}
public static SqmPredicate combinePredicates(SqmPredicate baseRestriction, SqmPredicate incomingRestriction) {
if ( baseRestriction == null ) {

View File

@ -6,9 +6,29 @@
*/
package org.hibernate.query.sqm.sql;
import jakarta.persistence.TemporalType;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.hibernate.HibernateException;
import org.hibernate.Internal;
import org.hibernate.LockMode;
@ -174,6 +194,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPluralPartJoin;
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedFrom;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.query.sqm.tree.expression.AsWrapperSqmExpression;
import org.hibernate.query.sqm.tree.expression.Conversion;
@ -405,30 +426,12 @@ import org.hibernate.type.internal.BasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.UserVersionType;
import org.hibernate.usertype.internal.AbstractTimeZoneStorageCompositeUserType;
import org.jboss.logging.Logger;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import jakarta.persistence.TemporalType;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type;
import static jakarta.persistence.metamodel.Type.PersistenceType.ENTITY;
import static java.util.Collections.singletonList;
@ -3255,7 +3258,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
consumeExplicitJoin( sqmJoin, actualTableGroup, actualTableGroup, true );
}
);
final List<SqmFrom<?, ?>> sqmTreats = sqmFrom.getSqmTreats();
final List<SqmTreatedFrom<?,?,?>> sqmTreats = sqmFrom.getSqmTreats();
if ( !sqmTreats.isEmpty() ) {
final SqlAstQueryPartProcessingState queryPartProcessingState = (SqlAstQueryPartProcessingState) getCurrentProcessingState();
queryPartProcessingState.registerTreatedFrom( sqmFrom );

View File

@ -19,7 +19,7 @@ import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType;
@ -31,7 +31,7 @@ import jakarta.persistence.criteria.JoinType;
* @author Steve Ebersole
*/
public abstract class AbstractSqmAttributeJoin<L, R>
extends AbstractSqmQualifiedJoin<L, R>
extends AbstractSqmJoin<L, R>
implements SqmAttributeJoin<L, R> {
private boolean fetched;
@ -77,8 +77,7 @@ public abstract class AbstractSqmAttributeJoin<L, R>
@Override
public SqmFrom<?, L> getLhs() {
//noinspection unchecked
return (SqmFrom<?, L>) super.getLhs();
return super.getLhs();
}
@Override
@ -91,8 +90,10 @@ public abstract class AbstractSqmAttributeJoin<L, R>
return fetched;
}
@Override
public JpaSelection<T> alias(String name) {
public JpaSelection<R> alias(String name) {
validateFetchAlias( name );
return super.alias( name );
}
@ -146,12 +147,16 @@ public abstract class AbstractSqmAttributeJoin<L, R>
}
@Override
public <S extends R> SqmAttributeJoin<L, S> treatAs(Class<S> treatTarget) {
return (SqmAttributeJoin<L, S>) super.treatAs( treatTarget );
}
public abstract <S extends R> SqmTreatedAttributeJoin<L,R,S> treatAs(Class<S> treatJavaType);
@Override
public <S extends R> SqmAttributeJoin<L, S> treatAs(EntityDomainType<S> treatTarget) {
return (SqmAttributeJoin<L, S>) super.treatAs( treatTarget );
}
public abstract <S extends R> SqmTreatedAttributeJoin<L, R, S> treatAs(EntityDomainType<S> treatTarget);
@Override
public abstract <S extends R> SqmTreatedAttributeJoin<L, R, S> treatAs(Class<S> treatJavaType, String alias);
@Override
public abstract <S extends R> SqmTreatedAttributeJoin<L, R, S> treatAs(EntityDomainType<S> treatTarget, String alias);
}

View File

@ -29,7 +29,6 @@ import org.hibernate.query.criteria.JpaCrossJoin;
import org.hibernate.query.criteria.JpaCteCriteria;
import org.hibernate.query.criteria.JpaDerivedJoin;
import org.hibernate.query.criteria.JpaEntityJoin;
import org.hibernate.query.criteria.JpaJoinedFrom;
import org.hibernate.query.criteria.JpaPath;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.hql.spi.SqmCreationState;
@ -73,7 +72,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
private String alias;
private List<SqmJoin<T, ?>> joins;
private List<SqmFrom<?, ?>> treats;
private List<SqmTreatedFrom<?,?,?>> treats;
protected AbstractSqmFrom(
NavigablePath navigablePath,
@ -139,7 +138,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
}
if ( treats != null ) {
target.treats = new ArrayList<>( treats.size() );
for ( SqmFrom<?, ?> treat : treats ) {
for ( SqmTreatedFrom<?,?,?> treat : treats ) {
target.treats.add( treat.copy( context ) );
}
}
@ -288,11 +287,11 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
}
@Override
public List<SqmFrom<?, ?>> getSqmTreats() {
public List<SqmTreatedFrom<?,?,?>> getSqmTreats() {
return treats == null ? Collections.emptyList() : treats;
}
protected <S, X extends SqmFrom<T, S>> X findTreat(ManagedDomainType<S> targetType, String alias) {
protected <S extends T, X extends SqmTreatedFrom<O,T,S>> X findTreat(ManagedDomainType<S> targetType, String alias) {
if ( treats != null ) {
for ( SqmFrom<?, ?> treat : treats ) {
if ( treat.getModel() == targetType ) {
@ -306,7 +305,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
return null;
}
protected <X extends SqmFrom<?, ?>> X addTreat(X treat) {
protected <X extends SqmTreatedFrom<?,?,?>> X addTreat(X treat) {
if ( treats == null ) {
treats = new ArrayList<>();
}
@ -607,25 +606,27 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
public <X> JpaDerivedJoin<X> join(Subquery<X> subquery, SqmJoinType joinType, boolean lateral, String alias) {
validateComplianceFromSubQuery();
final JpaDerivedJoin<X> join = new SqmDerivedJoin<>( (SqmSubQuery<X>) subquery, alias, joinType, lateral, findRoot() );
//noinspection unchecked
final JpaDerivedJoin<X> join = new SqmDerivedJoin<>( (SqmSubQuery<X>) subquery, alias, joinType, lateral, (SqmRoot<X>) findRoot() );
//noinspection unchecked
addSqmJoin( (SqmJoin<T, ?>) join );
return join;
}
@Override
public <X> JpaJoinedFrom<?, X> join(JpaCteCriteria<X> cte) {
public <X> SqmJoin<?, X> join(JpaCteCriteria<X> cte) {
return join( cte, SqmJoinType.INNER, null );
}
@Override
public <X> JpaJoinedFrom<?, X> join(JpaCteCriteria<X> cte, SqmJoinType joinType) {
public <X> SqmJoin<?, X> join(JpaCteCriteria<X> cte, SqmJoinType joinType) {
return join( cte, joinType, null );
}
public <X> JpaJoinedFrom<?, X> join(JpaCteCriteria<X> cte, SqmJoinType joinType, String alias) {
public <X> SqmJoin<?, X> join(JpaCteCriteria<X> cte, SqmJoinType joinType, String alias) {
validateComplianceFromSubQuery();
final JpaJoinedFrom<?, X> join = new SqmCteJoin<>( ( SqmCteStatement<X> ) cte, alias, joinType, findRoot() );
//noinspection unchecked
final SqmJoin<?, X> join = new SqmCteJoin<>( ( SqmCteStatement<X> ) cte, alias, joinType, (SqmRoot<X>) findRoot() );
//noinspection unchecked
addSqmJoin( (SqmJoin<T, ?>) join );
return join;
@ -646,7 +647,8 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
@Override
public <X> JpaCrossJoin<X> crossJoin(EntityDomainType<X> entity) {
final SqmCrossJoin<X> crossJoin = new SqmCrossJoin<>( entity, null, findRoot() );
//noinspection unchecked
final SqmCrossJoin<X> crossJoin = new SqmCrossJoin<>( entity, null, (SqmRoot<X>) findRoot() );
// noinspection unchecked
addSqmJoin( (SqmJoin<T, ?>) crossJoin );
return crossJoin;

View File

@ -6,23 +6,33 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.spi.NavigablePath;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmJoin;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public abstract class AbstractSqmJoin<O,T> extends AbstractSqmFrom<O,T> implements SqmJoin<O,T> {
public abstract class AbstractSqmJoin<L, R> extends AbstractSqmFrom<L, R> implements SqmJoin<L, R> {
private final SqmJoinType joinType;
private SqmPredicate onClausePredicate;
public AbstractSqmJoin(
NavigablePath navigablePath,
SqmPathSource<T> referencedNavigable,
SqmFrom<?, ?> lhs,
SqmPathSource<R> referencedNavigable,
SqmFrom<?, L> lhs,
String alias,
SqmJoinType joinType,
NodeBuilder nodeBuilder) {
@ -34,4 +44,96 @@ public abstract class AbstractSqmJoin<O,T> extends AbstractSqmFrom<O,T> implemen
public SqmJoinType getSqmJoinType() {
return joinType;
}
@Override
public SqmPredicate getJoinPredicate() {
return onClausePredicate;
}
@Override
public void setJoinPredicate(SqmPredicate predicate) {
if ( log.isTraceEnabled() ) {
log.tracef(
"Setting join predicate [%s] (was [%s])",
predicate.toString(),
this.onClausePredicate == null ? "<null>" : this.onClausePredicate.toString()
);
}
this.onClausePredicate = predicate;
}
public void applyRestriction(SqmPredicate restriction) {
if ( this.onClausePredicate == null ) {
this.onClausePredicate = restriction;
}
else {
this.onClausePredicate = nodeBuilder().and( onClausePredicate, restriction );
}
}
protected void copyTo(AbstractSqmJoin<L, R> target, SqmCopyContext context) {
super.copyTo( target, context );
target.onClausePredicate = onClausePredicate == null ? null : onClausePredicate.copy( context );
}
@Override
public <S extends R> SqmTreatedJoin<L, R, S> treatAs(Class<S> treatTarget) {
return treatAs( treatTarget, null );
}
@Override
public <S extends R> SqmTreatedJoin<L, R, S> treatAs(EntityDomainType<S> treatTarget) {
return treatAs( treatTarget, null );
}
@Override
public abstract <S extends R> SqmTreatedJoin<L, R, S> treatAs(Class<S> treatJavaType, String alias);
@Override
public abstract <S extends R> SqmTreatedJoin<L, R, S> treatAs(EntityDomainType<S> treatTarget, String alias);
@Override
public SqmFrom<?, L> getLhs() {
//noinspection unchecked
return (SqmFrom<?, L>) super.getLhs();
}
@Override
public SqmFrom<?, L> getParent() {
return getLhs();
}
@Override
public JoinType getJoinType() {
return joinType.getCorrespondingJpaJoinType();
}
@Override
public SqmPredicate getOn() {
return getJoinPredicate();
}
@Override
public SqmJoin<L, R> on(JpaExpression<Boolean> restriction) {
applyRestriction( nodeBuilder().wrap( restriction ) );
return this;
}
@Override
public SqmJoin<L, R> on(Expression<Boolean> restriction) {
applyRestriction( nodeBuilder().wrap( restriction ) );
return this;
}
@Override
public SqmJoin<L, R> on(JpaPredicate... restrictions) {
applyRestriction( nodeBuilder().wrap( restrictions ) );
return this;
}
@Override
public SqmJoin<L, R> on(Predicate... restrictions) {
applyRestriction( nodeBuilder().wrap( restrictions ) );
return this;
}
}

View File

@ -16,13 +16,21 @@ import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
/**
* Base support for joins to plural attributes
*
* @param <L> The left-hand side of the join
* @param <C> The collection type
* @param <E> The collection's element type
*
* @author Steve Ebersole
*/
public abstract class AbstractSqmPluralJoin<O,C,E> extends AbstractSqmAttributeJoin<O,E> implements JpaJoin<O,E>, PluralJoin<O,C,E> {
public abstract class AbstractSqmPluralJoin<L,C,E>
extends AbstractSqmAttributeJoin<L,E>
implements JpaJoin<L,E>, PluralJoin<L,C,E> {
public AbstractSqmPluralJoin(
SqmFrom<?, O> lhs,
PluralPersistentAttribute<O,C,E> joinedNavigable,
SqmFrom<?, L> lhs,
PluralPersistentAttribute<L,C,E> joinedNavigable,
String alias,
SqmJoinType joinType,
boolean fetched,
@ -31,9 +39,9 @@ public abstract class AbstractSqmPluralJoin<O,C,E> extends AbstractSqmAttributeJ
}
protected AbstractSqmPluralJoin(
SqmFrom<?, O> lhs,
SqmFrom<?, L> lhs,
NavigablePath navigablePath,
PluralPersistentAttribute<O,C,E> joinedNavigable,
PluralPersistentAttribute<L,C,E> joinedNavigable,
String alias,
SqmJoinType joinType,
boolean fetched,
@ -42,7 +50,7 @@ public abstract class AbstractSqmPluralJoin<O,C,E> extends AbstractSqmAttributeJ
}
@Override
public PluralPersistentAttribute<O, C, E> getModel() {
return (PluralPersistentAttribute<O, C, E>) super.getNodeType();
public PluralPersistentAttribute<L, C, E> getModel() {
return (PluralPersistentAttribute<L, C, E>) super.getNodeType();
}
}

View File

@ -1,111 +0,0 @@
/*
* 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.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaJoinedFrom;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public abstract class AbstractSqmQualifiedJoin<L, R> extends AbstractSqmJoin<L,R> implements SqmQualifiedJoin<L,R>, JpaJoinedFrom<L, R> {
private SqmPredicate onClausePredicate;
public AbstractSqmQualifiedJoin(
NavigablePath navigablePath,
SqmPathSource<R> referencedNavigable,
SqmFrom<?, ?> lhs, String alias, SqmJoinType joinType, NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, alias, joinType, nodeBuilder );
}
protected void copyTo(AbstractSqmQualifiedJoin<L, R> target, SqmCopyContext context) {
super.copyTo( target, context );
target.onClausePredicate = onClausePredicate == null ? null : onClausePredicate.copy( context );
}
@Override
public JpaPredicate getOn() {
return onClausePredicate;
}
@Override
public SqmPredicate getJoinPredicate() {
return onClausePredicate;
}
@Override
public void setJoinPredicate(SqmPredicate predicate) {
if ( log.isTraceEnabled() ) {
log.tracef(
"Setting join predicate [%s] (was [%s])",
predicate.toString(),
this.onClausePredicate == null ? "<null>" : this.onClausePredicate.toString()
);
}
this.onClausePredicate = predicate;
}
public void applyRestriction(SqmPredicate restriction) {
if ( this.onClausePredicate == null ) {
this.onClausePredicate = restriction;
}
else {
this.onClausePredicate = nodeBuilder().and( onClausePredicate, restriction );
}
}
@Override
public <S extends R> SqmQualifiedJoin<L, S> treatAs(Class<S> treatAsType) {
return treatAs( treatAsType, null );
}
@Override
public <S extends R> SqmQualifiedJoin<L, S> treatAs(EntityDomainType<S> treatAsType) {
return treatAs( treatAsType, null );
}
@Override
public JpaJoinedFrom<L, R> on(JpaExpression<Boolean> restriction) {
applyRestriction( nodeBuilder().wrap( restriction ) );
return this;
}
@Override
public JpaJoinedFrom<L, R> on(Expression<Boolean> restriction) {
applyRestriction( nodeBuilder().wrap( restriction ) );
return this;
}
@Override
public JpaJoinedFrom<L, R> on(JpaPredicate... restrictions) {
applyRestriction( nodeBuilder().wrap( restrictions ) );
return this;
}
@Override
public JpaJoinedFrom<L, R> on(Predicate... restrictions) {
applyRestriction( nodeBuilder().wrap( restrictions ) );
return this;
}
}

View File

@ -19,10 +19,12 @@ import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;

View File

@ -19,12 +19,12 @@ import org.hibernate.query.sqm.tree.from.SqmRoot;
/**
* @author Christian Beikov
*/
public class SqmCorrelatedMapJoin<O, K, V> extends SqmMapJoin<O, K, V> implements SqmCorrelation<O, V> {
public class SqmCorrelatedMapJoin<L,K,V> extends SqmMapJoin<L,K,V> implements SqmCorrelation<L,V> {
private final SqmCorrelatedRootJoin<O> correlatedRootJoin;
private final SqmMapJoin<O, K, V> correlationParent;
private final SqmCorrelatedRootJoin<L> correlatedRootJoin;
private final SqmMapJoin<L, K, V> correlationParent;
public SqmCorrelatedMapJoin(SqmMapJoin<O, K, V> correlationParent) {
public SqmCorrelatedMapJoin(SqmMapJoin<L, K, V> correlationParent) {
super(
correlationParent.getLhs(),
correlationParent.getNavigablePath(),
@ -39,26 +39,26 @@ public class SqmCorrelatedMapJoin<O, K, V> extends SqmMapJoin<O, K, V> implement
}
private SqmCorrelatedMapJoin(
SqmFrom<?, O> lhs,
MapPersistentAttribute<O,K,V> attribute,
SqmFrom<?, L> lhs,
MapPersistentAttribute<L,K,V> attribute,
String alias,
SqmJoinType sqmJoinType,
boolean fetched,
NodeBuilder nodeBuilder,
SqmCorrelatedRootJoin<O> correlatedRootJoin,
SqmMapJoin<O, K, V> correlationParent) {
SqmCorrelatedRootJoin<L> correlatedRootJoin,
SqmMapJoin<L, K, V> correlationParent) {
super( lhs, correlationParent.getNavigablePath(), attribute, alias, sqmJoinType, fetched, nodeBuilder );
this.correlatedRootJoin = correlatedRootJoin;
this.correlationParent = correlationParent;
}
@Override
public SqmCorrelatedMapJoin<O, K, V> copy(SqmCopyContext context) {
final SqmCorrelatedMapJoin<O, K, V> existing = context.getCopy( this );
public SqmCorrelatedMapJoin<L, K, V> copy(SqmCopyContext context) {
final SqmCorrelatedMapJoin<L, K, V> existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}
final SqmCorrelatedMapJoin<O, K, V> path = context.registerCopy(
final SqmCorrelatedMapJoin<L, K, V> path = context.registerCopy(
this,
new SqmCorrelatedMapJoin<>(
getLhs().copy( context ),
@ -76,7 +76,7 @@ public class SqmCorrelatedMapJoin<O, K, V> extends SqmMapJoin<O, K, V> implement
}
@Override
public SqmMapJoin<O, K, V> getCorrelationParent() {
public SqmMapJoin<L, K, V> getCorrelationParent() {
return correlationParent;
}
@ -91,12 +91,12 @@ public class SqmCorrelatedMapJoin<O, K, V> extends SqmMapJoin<O, K, V> implement
}
@Override
public SqmRoot<O> getCorrelatedRoot() {
public SqmRoot<L> getCorrelatedRoot() {
return correlatedRootJoin;
}
@Override
public SqmCorrelatedMapJoin<O, K, V> makeCopy(SqmCreationProcessingState creationProcessingState) {
public SqmCorrelatedMapJoin<L, K, V> makeCopy(SqmCreationProcessingState creationProcessingState) {
final SqmPathRegistry pathRegistry = creationProcessingState.getPathRegistry();
return new SqmCorrelatedMapJoin<>(
pathRegistry.findFromByPath( getLhs().getNavigablePath() ),

View File

@ -22,7 +22,7 @@ public class SqmCorrelatedPluralPartJoin<O, T> extends SqmPluralPartJoin<O, T> i
public SqmCorrelatedPluralPartJoin(SqmPluralPartJoin<O, T> correlationParent) {
super(
(SqmFrom<?, O>) correlationParent.getLhs(),
correlationParent.getLhs(),
correlationParent.getNavigablePath(),
correlationParent.getReferencedPathSource(),
correlationParent.getExplicitAlias(),
@ -52,11 +52,6 @@ public class SqmCorrelatedPluralPartJoin<O, T> extends SqmPluralPartJoin<O, T> i
return walker.visitCorrelatedPluralPartJoin( this );
}
@Override
public SqmFrom<?, T> getLhs() {
return (SqmFrom<?, T>) super.getLhs();
}
@Override
public SqmPluralPartJoin<O, T> getCorrelationParent() {
return correlationParent;

View File

@ -13,9 +13,13 @@ import org.hibernate.query.sqm.tree.from.SqmRoot;
* Specialization of {@link SqmFrom} for sub-query correlations
*
* @see org.hibernate.query.criteria.JpaSubQuery#correlate
*
* @param <L> The left-hand side of the correlation. See {@linkplain #getCorrelatedRoot()}
* @param <R> The right-hand side of the correlation, which is the type of this node.
*
* @author Steve Ebersole
*/
public interface SqmCorrelation<O, T> extends SqmFrom<O, T>, SqmPathWrapper<T, T> {
SqmRoot<O> getCorrelatedRoot();
public interface SqmCorrelation<L,R> extends SqmFrom<L,R>, SqmPathWrapper<R,R> {
SqmRoot<L> getCorrelatedRoot();
}

View File

@ -15,7 +15,6 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.spi.NavigablePath;
@ -108,22 +107,22 @@ public class SqmDerivedRoot<T> extends SqmRoot<T> implements JpaDerivedRoot<T> {
}
@Override
public <S extends T> SqmFrom<T, S> treatAs(Class<S> treatJavaType) throws PathException {
public <S extends T> SqmTreatedFrom<T, T, S> treatAs(Class<S> treatJavaType) throws PathException {
throw new UnsupportedOperationException( "Derived roots can not be treated" );
}
@Override
public <S extends T> SqmFrom<T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
public <S extends T> SqmTreatedFrom<T, T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
throw new UnsupportedOperationException( "Derived roots can not be treated" );
}
@Override
public <S extends T> SqmFrom<T, S> treatAs(Class<S> treatJavaType, String alias) {
public <S extends T> SqmTreatedFrom<T, T, S> treatAs(Class<S> treatJavaType, String alias) {
throw new UnsupportedOperationException( "Derived roots can not be treated" );
}
@Override
public <S extends T> SqmFrom<T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
public <S extends T> SqmTreatedFrom<T, T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
throw new UnsupportedOperationException( "Derived roots can not be treated" );
}
}

View File

@ -12,12 +12,9 @@ import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.function.FunctionArgumentException;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.spi.NavigablePath;
/**
@ -86,12 +83,12 @@ public class SqmFkExpression<T> extends AbstractSqmPath<T> {
}
@Override
public <S extends T> SqmPath<S> treatAs(Class<S> treatJavaType) {
public <S extends T> SqmTreatedPath<T,S> treatAs(Class<S> treatJavaType) {
throw new FunctionArgumentException( "Fk paths cannot be TREAT-ed" );
}
@Override
public <S extends T> SqmPath<S> treatAs(EntityDomainType<S> treatTarget) {
public <S extends T> SqmTreatedPath<T,S> treatAs(EntityDomainType<S> treatTarget) {
throw new FunctionArgumentException( "Fk paths cannot be TREAT-ed" );
}

View File

@ -9,12 +9,8 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.BasicSqmPathSource;
import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource;
import org.hibernate.query.NotIndexedCollectionException;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.hql.spi.SqmPathRegistry;
import org.hibernate.query.spi.QueryEngine;
@ -22,14 +18,11 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.FunctionArgumentException;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmFunction;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.BasicPluralType;
import org.hibernate.type.BasicType;
@ -161,12 +154,12 @@ public class SqmFunctionPath<T> extends AbstractSqmPath<T> {
}
@Override
public <S extends T> SqmPath<S> treatAs(Class<S> treatJavaType) {
public <S extends T> SqmTreatedPath<T,S> treatAs(Class<S> treatJavaType) {
throw new FunctionArgumentException( "Embeddable paths cannot be TREAT-ed" );
}
@Override
public <S extends T> SqmPath<S> treatAs(EntityDomainType<S> treatTarget) {
public <S extends T> SqmTreatedPath<T,S> treatAs(EntityDomainType<S> treatTarget) {
throw new FunctionArgumentException( "Embeddable paths cannot be TREAT-ed" );
}
}

View File

@ -7,34 +7,35 @@
package org.hibernate.query.sqm.tree.domain;
import java.util.Map;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.TreatableDomainType;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaMapJoin;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public class SqmMapJoin<O, K, V>
extends AbstractSqmPluralJoin<O, Map<K, V>, V>
implements JpaMapJoin<O, K, V> {
public class SqmMapJoin<L, K, V>
extends AbstractSqmPluralJoin<L, Map<K, V>, V>
implements JpaMapJoin<L, K, V> {
public SqmMapJoin(
SqmFrom<?,O> lhs,
MapPersistentAttribute<O, K, V> pluralValuedNavigable,
SqmFrom<?, L> lhs,
MapPersistentAttribute<L, K, V> pluralValuedNavigable,
String alias,
SqmJoinType sqmJoinType,
boolean fetched,
@ -43,9 +44,9 @@ public class SqmMapJoin<O, K, V>
}
protected SqmMapJoin(
SqmFrom<?, O> lhs,
SqmFrom<?, L> lhs,
NavigablePath navigablePath,
MapPersistentAttribute<O, K, V> pluralValuedNavigable,
MapPersistentAttribute<L, K, V> pluralValuedNavigable,
String alias,
SqmJoinType joinType,
boolean fetched,
@ -54,13 +55,13 @@ public class SqmMapJoin<O, K, V>
}
@Override
public SqmMapJoin<O, K, V> copy(SqmCopyContext context) {
final SqmMapJoin<O, K, V> existing = context.getCopy( this );
public SqmMapJoin<L, K, V> copy(SqmCopyContext context) {
final SqmMapJoin<L, K, V> existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}
final SqmFrom<?, O> lhsCopy = getLhs().copy( context );
final SqmMapJoin<O, K, V> path = context.registerCopy(
final SqmFrom<?, L> lhsCopy = getLhs().copy( context );
final SqmMapJoin<L, K, V> path = context.registerCopy(
this,
new SqmMapJoin<>(
lhsCopy,
@ -77,8 +78,8 @@ public class SqmMapJoin<O, K, V>
}
@Override
public MapPersistentAttribute<O, K, V> getModel() {
return (MapPersistentAttribute<O, K, V>) super.getModel();
public MapPersistentAttribute<L, K, V> getModel() {
return (MapPersistentAttribute<L, K, V>) super.getModel();
}
@Override
@ -87,7 +88,7 @@ public class SqmMapJoin<O, K, V>
}
@Override
public MapPersistentAttribute<O, K, V> getAttribute() {
public MapPersistentAttribute<L, K, V> getAttribute() {
return getModel();
}
@ -112,54 +113,44 @@ public class SqmMapJoin<O, K, V>
}
@Override
public SqmMapJoin<O, K, V> on(JpaExpression<Boolean> restriction) {
return (SqmMapJoin<O, K, V>) super.on( restriction );
public SqmMapJoin<L, K, V> on(JpaExpression<Boolean> restriction) {
return (SqmMapJoin<L, K, V>) super.on( restriction );
}
@Override
public SqmMapJoin<O, K, V> on(Expression<Boolean> restriction) {
return (SqmMapJoin<O, K, V>) super.on( restriction );
public SqmMapJoin<L, K, V> on(Expression<Boolean> restriction) {
return (SqmMapJoin<L, K, V>) super.on( restriction );
}
@Override
public SqmMapJoin<O, K, V> on(JpaPredicate... restrictions) {
return (SqmMapJoin<O, K, V>) super.on( restrictions );
public SqmMapJoin<L, K, V> on(JpaPredicate... restrictions) {
return (SqmMapJoin<L, K, V>) super.on( restrictions );
}
@Override
public SqmMapJoin<O, K, V> on(Predicate... restrictions) {
return (SqmMapJoin<O, K, V>) super.on( restrictions );
public SqmMapJoin<L, K, V> on(Predicate... restrictions) {
return (SqmMapJoin<L, K, V>) super.on( restrictions );
}
@Override
public SqmCorrelatedMapJoin<O, K, V> createCorrelation() {
public SqmCorrelatedMapJoin<L, K, V> createCorrelation() {
return new SqmCorrelatedMapJoin<>( this );
}
@Override
public <S extends V> SqmTreatedMapJoin<O, K, V, S> treatAs(Class<S> treatJavaType) {
public <S extends V> SqmTreatedMapJoin<L, K, V, S> treatAs(Class<S> treatJavaType) {
return treatAs( treatJavaType, null );
}
@Override
public <S extends V> SqmTreatedMapJoin<O, K, V, S> treatAs(EntityDomainType<S> treatTarget) {
return treatAs( treatTarget, null );
}
@Override
public <S extends V> SqmTreatedMapJoin<O, K, V, S> treatAs(Class<S> treatJavaType, String alias) {
public <S extends V> SqmTreatedMapJoin<L, K, V, S> treatAs(Class<S> treatJavaType, String alias) {
return treatAs( treatJavaType, alias, false );
}
@Override
public <S extends V> SqmTreatedMapJoin<O, K, V, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
return treatAs( treatTarget, alias, false );
}
@Override
public <S extends V> SqmTreatedMapJoin<O, K, V, S> treatAs(Class<S> treatJavaType, String alias, boolean fetch) {
public <S extends V> SqmTreatedMapJoin<L, K, V, S> treatAs(Class<S> treatJavaType, String alias, boolean fetch) {
final ManagedDomainType<S> treatTarget = nodeBuilder().getDomainModel().managedType( treatJavaType );
final SqmTreatedMapJoin<O, K, V, S> treat = findTreat( treatTarget, alias );
final SqmTreatedMapJoin<L, K, V, S> treat = findTreat( treatTarget, alias );
if ( treat == null ) {
if ( treatTarget instanceof TreatableDomainType<?> ) {
return addTreat( new SqmTreatedMapJoin<>( this, (TreatableDomainType<S>) treatTarget, alias, fetch ) );
@ -172,8 +163,13 @@ public class SqmMapJoin<O, K, V>
}
@Override
public <S extends V> SqmTreatedMapJoin<O, K, V, S> treatAs(EntityDomainType<S> treatTarget, String alias, boolean fetch) {
final SqmTreatedMapJoin<O, K, V, S> treat = findTreat( treatTarget, alias );
public <S extends V> SqmTreatedMapJoin<L, K, V, S> treatAs(EntityDomainType<S> treatTarget) {
return treatAs( treatTarget, null );
}
@Override
public <S extends V> SqmTreatedMapJoin<L, K, V, S> treatAs(EntityDomainType<S> treatTarget, String alias, boolean fetch) {
final SqmTreatedMapJoin<L, K, V, S> treat = findTreat( treatTarget, alias );
if ( treat == null ) {
return addTreat( new SqmTreatedMapJoin<>( this, treatTarget, alias, fetch ) );
}
@ -181,7 +177,16 @@ public class SqmMapJoin<O, K, V>
}
@Override
public SqmMapJoin<O, K, V> makeCopy(SqmCreationProcessingState creationProcessingState) {
public <S extends V> SqmTreatedMapJoin<L, K, V, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
final SqmTreatedMapJoin<L, K, V, S> treat = findTreat( treatTarget, alias );
if ( treat == null ) {
return addTreat( new SqmTreatedMapJoin<>( this, treatTarget, alias ) );
}
return treat;
}
@Override
public SqmMapJoin<L, K, V> makeCopy(SqmCreationProcessingState creationProcessingState) {
return new SqmMapJoin<>(
creationProcessingState.getPathRegistry().findFromByPath( getLhs().getNavigablePath() ),
getAttribute(),

View File

@ -19,8 +19,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.SemanticException;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.criteria.JpaPath;
import org.hibernate.query.hql.spi.SemanticPathPart;
import org.hibernate.query.hql.spi.SqmCreationState;
@ -30,8 +28,13 @@ import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.spi.NavigablePath;
import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.metamodel.MapAttribute;
import jakarta.persistence.metamodel.PluralAttribute;
import jakarta.persistence.metamodel.SingularAttribute;
/**
* Models a reference to a part of the application's domain model as part of an SQM tree.
*
@ -117,10 +120,10 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
}
@Override
<S extends T> SqmPath<S> treatAs(Class<S> treatJavaType);
<S extends T> SqmTreatedPath<T,S> treatAs(Class<S> treatJavaType);
@Override
<S extends T> SqmPath<S> treatAs(EntityDomainType<S> treatTarget);
<S extends T> SqmTreatedPath<T,S> treatAs(EntityDomainType<S> treatTarget);
default SqmRoot<?> findRoot() {
final SqmPath<?> lhs = getLhs();

View File

@ -9,6 +9,7 @@ package org.hibernate.query.sqm.tree.domain;
import java.util.Locale;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
@ -17,13 +18,12 @@ import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
/**
* @author Christian Beikov
*/
public class SqmPluralPartJoin<O,T> extends AbstractSqmJoin<O,T> implements SqmQualifiedJoin<O, T> {
public class SqmPluralPartJoin<O,T> extends AbstractSqmJoin<O,T> {
public SqmPluralPartJoin(
SqmFrom<?,O> lhs,
@ -99,29 +99,55 @@ public class SqmPluralPartJoin<O,T> extends AbstractSqmJoin<O,T> implements SqmQ
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitPluralPartJoin( this );
}
//
// @Override
// public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(Class<S> treatJavaType) {
// return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
// }
//
// @Override
// public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget) {
// return treatAs( treatTarget, null );
// }
//
// @Override
// public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(Class<S> treatJavaType, String alias) {
// return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ), alias );
// }
//
// @Override
// public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget, String alias) {
// final SqmTreatedPluralPartJoin<O, T, S> treat = findTreat( treatTarget, alias );
// if ( treat == null ) {
// return addTreat( new SqmTreatedPluralPartJoin<>( this, treatTarget, alias ) );
// }
// return treat;
// }
@Override
public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(Class<S> treatJavaType) {
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
public PersistentAttribute<? super O, ?> getAttribute() {
return null;
}
@Override
public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget) {
return treatAs( treatTarget, null );
public <S extends T> SqmTreatedPluralPartJoin<O, T, S> treatAs(Class<S> treatJavaType) {
return null;
}
@Override
public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(Class<S> treatJavaType, String alias) {
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ), alias );
public <S extends T> SqmTreatedJoin<O, T, S> treatAs(EntityDomainType<S> treatTarget) {
return null;
}
@Override
public <S extends T> SqmTreatedPluralPartJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget, String alias) {
final SqmTreatedPluralPartJoin<O, T, S> treat = findTreat( treatTarget, alias );
if ( treat == null ) {
return addTreat( new SqmTreatedPluralPartJoin<>( this, treatTarget, alias ) );
}
return treat;
public <S extends T> SqmTreatedJoin<O, T, S> treatAs(Class<S> treatJavaType, String alias) {
return null;
}
@Override
public <S extends T> SqmTreatedJoin<O, T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
return null;
}
@Override

View File

@ -12,7 +12,6 @@ import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.NotIndexedCollectionException;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.PathException;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.hql.spi.SqmPathRegistry;
@ -22,7 +21,8 @@ import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
import org.hibernate.query.sqm.tree.from.SqmJoin;
import org.hibernate.spi.NavigablePath;
/**
* An SqmPath for plural attribute paths
@ -127,7 +127,7 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
if ( path == null ) {
final PluralPersistentAttribute<?, ?, E> referencedPathSource = getReferencedPathSource();
final SqmFrom<?, Object> parent = pathRegistry.resolveFrom( getLhs() );
final SqmQualifiedJoin<Object, ?> join;
final SqmJoin<Object, ?> join;
final SqmExpression<?> index;
if ( referencedPathSource instanceof ListPersistentAttribute<?, ?> ) {
//noinspection unchecked

View File

@ -23,6 +23,7 @@ import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin;
import org.hibernate.spi.NavigablePath;
/**
@ -41,7 +42,7 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
public SqmSingularJoin(
SqmFrom<?,O> lhs,
SqmJoinable joinedNavigable,
SqmJoinable<? extends O, T> joinedNavigable,
String alias,
SqmJoinType joinType,
boolean fetched,
@ -99,22 +100,22 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
}
@Override
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(Class<S> treatJavaType) {
public <S extends T> SqmTreatedAttributeJoin<O, T, S> treatAs(Class<S> treatJavaType) {
return treatAs( treatJavaType, null );
}
@Override
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget) {
public <S extends T> SqmTreatedAttributeJoin<O, T, S> treatAs(EntityDomainType<S> treatTarget) {
return treatAs( treatTarget, null );
}
@Override
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(Class<S> treatJavaType, String alias) {
public <S extends T> SqmTreatedAttributeJoin<O, T, S> treatAs(Class<S> treatJavaType, String alias) {
return treatAs( treatJavaType, alias, false );
}
@Override
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget, String alias) {
public <S extends T> SqmTreatedAttributeJoin<O, T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
return treatAs( treatTarget, alias, false );
}

View File

@ -9,29 +9,35 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.model.domain.BagPersistentAttribute;
import org.hibernate.metamodel.model.domain.TreatableDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> implements SqmTreatedPath<T,S> {
private final SqmBagJoin<O, T> wrappedPath;
private final TreatableDomainType<S> treatTarget;
public class SqmTreatedBagJoin<L, R, R1 extends R> extends SqmBagJoin<L, R1> implements SqmTreatedAttributeJoin<L, R, R1> {
private final SqmBagJoin<L, R> wrappedPath;
private final TreatableDomainType<R1> treatTarget;
public SqmTreatedBagJoin(
SqmBagJoin<O, T> wrappedPath,
TreatableDomainType<S> treatTarget,
SqmBagJoin<L, R> wrappedPath,
TreatableDomainType<R1> treatTarget,
String alias) {
this( wrappedPath, treatTarget, alias, false );
}
public SqmTreatedBagJoin(
SqmBagJoin<O, T> wrappedPath,
TreatableDomainType<S> treatTarget,
SqmBagJoin<L, R> wrappedPath,
TreatableDomainType<R1> treatTarget,
String alias,
boolean fetched) {
//noinspection unchecked
@ -40,7 +46,7 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
wrappedPath.getNavigablePath()
.append( CollectionPart.Nature.ELEMENT.getName() )
.treatAs( treatTarget.getTypeName(), alias ),
(BagPersistentAttribute<O, S>) wrappedPath.getAttribute(),
(BagPersistentAttribute<L, R1>) wrappedPath.getAttribute(),
alias,
wrappedPath.getSqmJoinType(),
fetched,
@ -52,15 +58,15 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
private SqmTreatedBagJoin(
NavigablePath navigablePath,
SqmBagJoin<O, T> wrappedPath,
TreatableDomainType<S> treatTarget,
SqmBagJoin<L, R> wrappedPath,
TreatableDomainType<R1> treatTarget,
String alias,
boolean fetched) {
//noinspection unchecked
super(
wrappedPath.getLhs(),
navigablePath,
(BagPersistentAttribute<O, S>) wrappedPath.getAttribute(),
(BagPersistentAttribute<L, R1>) wrappedPath.getAttribute(),
alias,
wrappedPath.getSqmJoinType(),
wrappedPath.isFetched(),
@ -71,12 +77,12 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
}
@Override
public SqmTreatedBagJoin<O, T, S> copy(SqmCopyContext context) {
final SqmTreatedBagJoin<O, T, S> existing = context.getCopy( this );
public SqmTreatedBagJoin<L, R, R1> copy(SqmCopyContext context) {
final SqmTreatedBagJoin<L, R, R1> existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}
final SqmTreatedBagJoin<O, T, S> path = context.registerCopy(
final SqmTreatedBagJoin<L, R, R1> path = context.registerCopy(
this,
new SqmTreatedBagJoin<>(
getNavigablePath(),
@ -91,22 +97,22 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
}
@Override
public SqmBagJoin<O,T> getWrappedPath() {
public SqmBagJoin<L, R> getWrappedPath() {
return wrappedPath;
}
@Override
public TreatableDomainType<S> getTreatTarget() {
public TreatableDomainType<R1> getTreatTarget() {
return treatTarget;
}
@Override
public SqmPathSource<S> getNodeType() {
public SqmPathSource<R1> getNodeType() {
return treatTarget;
}
@Override
public TreatableDomainType<S> getReferencedPathSource() {
public TreatableDomainType<R1> getReferencedPathSource() {
return treatTarget;
}
@ -116,7 +122,7 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
}
@Override
public SqmAttributeJoin<O, S> makeCopy(SqmCreationProcessingState creationProcessingState) {
public SqmAttributeJoin<L, R1> makeCopy(SqmCreationProcessingState creationProcessingState) {
return new SqmTreatedBagJoin<>( wrappedPath, treatTarget, getAlias() );
}
@ -128,4 +134,24 @@ public class SqmTreatedBagJoin<O,T, S extends T> extends SqmBagJoin<O,S> impleme
sb.append( treatTarget.getTypeName() );
sb.append( ')' );
}
@Override
public SqmTreatedBagJoin<L,R,R1> on(JpaExpression<Boolean> restriction) {
return (SqmTreatedBagJoin<L, R, R1>) super.on( restriction );
}
@Override
public SqmTreatedBagJoin<L,R,R1> on(Expression<Boolean> restriction) {
return (SqmTreatedBagJoin<L, R, R1>) super.on( restriction );
}
@Override
public SqmTreatedBagJoin<L,R,R1> on(JpaPredicate... restrictions) {
return (SqmTreatedBagJoin<L, R, R1>) super.on( restrictions );
}
@Override
public SqmTreatedBagJoin<L,R,R1> on(Predicate... restrictions) {
return (SqmTreatedBagJoin<L, R, R1>) super.on( restrictions );
}
}

View File

@ -13,36 +13,24 @@ import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
import org.hibernate.spi.NavigablePath;
/**
* A TREAT form of {@linkplain SqmCrossJoin}
*
* @author Steve Ebersole
*/
public class SqmTreatedCrossJoin<T, S extends T> extends SqmCrossJoin<S> implements SqmTreatedPath<T, S> {
private final SqmCrossJoin<T> wrappedPath;
private final EntityDomainType<S> treatTarget;
public SqmTreatedCrossJoin(
SqmCrossJoin<T> wrappedPath,
EntityDomainType<S> treatTarget,
String alias) {
//noinspection unchecked
super(
wrappedPath.getNavigablePath().treatAs( treatTarget.getHibernateEntityName(), alias ),
(EntityDomainType<S>) wrappedPath.getReferencedPathSource().getSqmPathType(),
alias,
wrappedPath.getRoot()
);
this.wrappedPath = wrappedPath;
this.treatTarget = treatTarget;
}
@SuppressWarnings("rawtypes")
public class SqmTreatedCrossJoin extends SqmCrossJoin implements SqmTreatedJoin {
private final SqmCrossJoin wrappedPath;
private final EntityDomainType treatTarget;
private SqmTreatedCrossJoin(
NavigablePath navigablePath,
SqmCrossJoin<T> wrappedPath,
EntityDomainType<S> treatTarget,
SqmCrossJoin<?> wrappedPath,
EntityDomainType<?> treatTarget,
String alias) {
//noinspection unchecked
super(
navigablePath,
(EntityDomainType<S>) wrappedPath.getReferencedPathSource().getSqmPathType(),
(EntityDomainType) wrappedPath.getReferencedPathSource().getSqmPathType(),
alias,
wrappedPath.getRoot()
);
@ -51,46 +39,50 @@ public class SqmTreatedCrossJoin<T, S extends T> extends SqmCrossJoin<S> impleme
}
@Override
public SqmTreatedCrossJoin<T, S> copy(SqmCopyContext context) {
final SqmTreatedCrossJoin<T, S> existing = context.getCopy( this );
public SqmTreatedCrossJoin copy(SqmCopyContext context) {
final SqmTreatedCrossJoin existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}
final SqmTreatedCrossJoin<T, S> path = context.registerCopy(
final SqmTreatedCrossJoin path = context.registerCopy(
this,
new SqmTreatedCrossJoin<>(
new SqmTreatedCrossJoin(
getNavigablePath(),
wrappedPath.copy( context ),
treatTarget,
getExplicitAlias()
)
);
//noinspection unchecked
copyTo( path, context );
return path;
}
@Override
public EntityDomainType<S> getTreatTarget() {
public EntityDomainType getTreatTarget() {
return treatTarget;
}
@Override
public EntityDomainType<S> getModel() {
public EntityDomainType getModel() {
return getTreatTarget();
}
@SuppressWarnings("rawtypes")
@Override
public SqmPath<T> getWrappedPath() {
public SqmPath getWrappedPath() {
return wrappedPath;
}
@SuppressWarnings({ "rawtypes" })
@Override
public SqmPathSource<S> getNodeType() {
public SqmPathSource getNodeType() {
return treatTarget;
}
@SuppressWarnings({ "rawtypes" })
@Override
public EntityDomainType<S> getReferencedPathSource() {
public EntityDomainType getReferencedPathSource() {
return treatTarget;
}
@ -99,7 +91,6 @@ public class SqmTreatedCrossJoin<T, S extends T> extends SqmCrossJoin<S> impleme
return treatTarget;
}
@Override
public void appendHqlString(StringBuilder sb) {
sb.append( "treat(" );
@ -108,4 +99,28 @@ public class SqmTreatedCrossJoin<T, S extends T> extends SqmCrossJoin<S> impleme
sb.append( treatTarget.getName() );
sb.append( ')' );
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public SqmTreatedCrossJoin treatAs(Class treatJavaType, String alias) {
return super.treatAs( treatJavaType, alias );
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public SqmTreatedCrossJoin treatAs(EntityDomainType treatTarget, String alias) {
return super.treatAs( treatTarget, alias );
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public SqmTreatedCrossJoin treatAs(Class treatAsType) {
return super.treatAs( treatAsType );
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public SqmTreatedCrossJoin treatAs(EntityDomainType treatAsType) {
return super.treatAs( treatAsType );
}
}

View File

@ -15,7 +15,7 @@ import org.hibernate.spi.NavigablePath;
/**
* @author Steve Ebersole
*/
public class SqmTreatedEntityJoin<L,R,S extends R> extends SqmEntityJoin<L,S> implements SqmTreatedPath<R,S> {
public class SqmTreatedEntityJoin<L,R,S extends R> extends SqmEntityJoin<L,S> implements SqmTreatedJoin<L,R,S> {
private final SqmEntityJoin<L,R> wrappedPath;
private final EntityDomainType<S> treatTarget;

View File

@ -0,0 +1,32 @@
/*
* 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.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaTreatedFrom;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.from.SqmFrom;
/**
* @author Steve Ebersole
*/
public interface SqmTreatedFrom<L,R,R1 extends R> extends SqmFrom<L,R1>, SqmTreatedPath<R,R1>, JpaTreatedFrom<L,R,R1> {
@Override
<S extends R1> SqmTreatedFrom<L, R1, S> treatAs(Class<S> treatJavaType);
@Override
<S extends R1> SqmTreatedFrom<L, R1, S> treatAs(EntityDomainType<S> treatTarget);
@Override
<S extends R1> SqmTreatedFrom<L, R1, S> treatAs(Class<S> treatJavaType, String alias);
@Override
<S extends R1> SqmTreatedFrom<L, R1, S> treatAs(EntityDomainType<S> treatTarget, String alias);
@Override
SqmTreatedFrom<L,R,R1> copy(SqmCopyContext context);
}

View File

@ -0,0 +1,27 @@
/*
* 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.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaTreatedJoin;
/**
* @author Steve Ebersole
*/
public interface SqmTreatedJoin<L,R,R1 extends R> extends SqmTreatedFrom<L,R,R1>, JpaTreatedJoin<L,R,R1> {
@Override
<S extends R1> SqmTreatedJoin<L, R1, S> treatAs(Class<S> treatJavaType);
@Override
<S extends R1> SqmTreatedJoin<L, R1, S> treatAs(EntityDomainType<S> treatTarget);
@Override
<S extends R1> SqmTreatedJoin<L, R1, S> treatAs(Class<S> treatJavaType, String alias);
@Override
<S extends R1> SqmTreatedJoin<L, R1, S> treatAs(EntityDomainType<S> treatTarget, String alias);
}

View File

@ -9,18 +9,24 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.TreatableDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public class SqmTreatedListJoin<O,T, S extends T> extends SqmListJoin<O,S> implements SqmTreatedPath<T,S> {
public class SqmTreatedListJoin<O,T, S extends T> extends SqmListJoin<O,S> implements SqmTreatedAttributeJoin<O,T,S> {
private final SqmListJoin<O,T> wrappedPath;
private final TreatableDomainType<S> treatTarget;
@ -125,6 +131,29 @@ public class SqmTreatedListJoin<O,T, S extends T> extends SqmListJoin<O,S> imple
return getWrappedPath().resolveIndexedAccess( selector, isTerminal, creationState );
}
@Override
public SqmTreatedListJoin<O,T,S> on(JpaExpression<Boolean> restriction) {
return (SqmTreatedListJoin<O,T,S>) super.on( restriction );
}
@Override
public SqmTreatedListJoin<O,T,S> on(Expression<Boolean> restriction) {
return (SqmTreatedListJoin<O, T, S>) super.on( restriction );
}
@Override
public SqmTreatedListJoin<O,T,S> on(JpaPredicate... restrictions) {
return (SqmTreatedListJoin<O, T, S>) super.on( restrictions );
}
@Override
public SqmTreatedListJoin<O,T,S> on(Predicate... restrictions) {
return (SqmTreatedListJoin<O, T, S>) super.on( restrictions );
}
@Override
public SqmAttributeJoin<O, S> makeCopy(SqmCreationProcessingState creationProcessingState) {
return new SqmTreatedListJoin<>( wrappedPath, treatTarget, getAlias() );

View File

@ -7,28 +7,35 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.TreatableDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public class SqmTreatedMapJoin<O, K, V, S extends V> extends SqmMapJoin<O, K, S> implements SqmTreatedPath<V, S> {
private final SqmMapJoin<O, K, V> wrappedPath;
public class SqmTreatedMapJoin<L, K, V, S extends V> extends SqmMapJoin<L, K, S> implements SqmTreatedAttributeJoin<L,V,S> {
private final SqmMapJoin<L, K, V> wrappedPath;
private final TreatableDomainType<S> treatTarget;
public SqmTreatedMapJoin(
SqmMapJoin<O, K, V> wrappedPath,
SqmMapJoin<L, K, V> wrappedPath,
TreatableDomainType<S> treatTarget,
String alias) {
this( wrappedPath, treatTarget, alias, false );
}
public SqmTreatedMapJoin(
SqmMapJoin<O, K, V> wrappedPath,
SqmMapJoin<L, K, V> wrappedPath,
TreatableDomainType<S> treatTarget,
String alias,
boolean fetched) {
@ -38,7 +45,7 @@ public class SqmTreatedMapJoin<O, K, V, S extends V> extends SqmMapJoin<O, K, S>
wrappedPath.getNavigablePath()
.append( CollectionPart.Nature.ELEMENT.getName() )
.treatAs( treatTarget.getTypeName(), alias ),
( (SqmMapJoin<O, K, S>) wrappedPath ).getModel(),
( (SqmMapJoin<L, K, S>) wrappedPath ).getModel(),
alias,
wrappedPath.getSqmJoinType(),
fetched,
@ -50,7 +57,7 @@ public class SqmTreatedMapJoin<O, K, V, S extends V> extends SqmMapJoin<O, K, S>
private SqmTreatedMapJoin(
NavigablePath navigablePath,
SqmMapJoin<O, K, V> wrappedPath,
SqmMapJoin<L, K, V> wrappedPath,
TreatableDomainType<S> treatTarget,
String alias,
boolean fetched) {
@ -58,7 +65,7 @@ public class SqmTreatedMapJoin<O, K, V, S extends V> extends SqmMapJoin<O, K, S>
super(
wrappedPath.getLhs(),
navigablePath,
( (SqmMapJoin<O, K, S>) wrappedPath ).getModel(),
( (SqmMapJoin<L, K, S>) wrappedPath ).getModel(),
alias,
wrappedPath.getSqmJoinType(),
fetched,
@ -69,12 +76,12 @@ public class SqmTreatedMapJoin<O, K, V, S extends V> extends SqmMapJoin<O, K, S>
}
@Override
public SqmTreatedMapJoin<O, K, V, S> copy(SqmCopyContext context) {
final SqmTreatedMapJoin<O, K, V, S> existing = context.getCopy( this );
public SqmTreatedMapJoin<L, K, V, S> copy(SqmCopyContext context) {
final SqmTreatedMapJoin<L, K, V, S> existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}
final SqmTreatedMapJoin<O, K, V, S> path = context.registerCopy(
final SqmTreatedMapJoin<L, K, V, S> path = context.registerCopy(
this,
new SqmTreatedMapJoin<>(
getNavigablePath(),
@ -89,7 +96,7 @@ public class SqmTreatedMapJoin<O, K, V, S extends V> extends SqmMapJoin<O, K, S>
}
@Override
public SqmMapJoin<O,K,V> getWrappedPath() {
public SqmMapJoin<L,K,V> getWrappedPath() {
return wrappedPath;
}
@ -114,7 +121,47 @@ public class SqmTreatedMapJoin<O, K, V, S extends V> extends SqmMapJoin<O, K, S>
}
@Override
public SqmMapJoin<O, K, S> makeCopy(SqmCreationProcessingState creationProcessingState) {
public <S1 extends S> SqmTreatedMapJoin<L, K, S, S1> treatAs(Class<S1> treatJavaType) {
return super.treatAs( treatJavaType );
}
@Override
public <S1 extends S> SqmTreatedMapJoin<L, K, S, S1> treatAs(EntityDomainType<S1> treatTarget) {
return super.treatAs( treatTarget );
}
@Override
public <S1 extends S> SqmTreatedMapJoin<L, K, S, S1> treatAs(Class<S1> treatJavaType, String alias) {
return super.treatAs( treatJavaType, alias );
}
@Override
public <S1 extends S> SqmTreatedMapJoin<L, K, S, S1> treatAs(EntityDomainType<S1> treatTarget, String alias) {
return super.treatAs( treatTarget, alias );
}
@Override
public SqmTreatedMapJoin<L, K, V, S> on(JpaExpression<Boolean> restriction) {
return (SqmTreatedMapJoin<L, K, V, S>) super.on( restriction );
}
@Override
public SqmTreatedMapJoin<L, K, V, S> on(Expression<Boolean> restriction) {
return (SqmTreatedMapJoin<L, K, V, S>) super.on( restriction );
}
@Override
public SqmTreatedMapJoin<L, K, V, S> on(JpaPredicate... restrictions) {
return (SqmTreatedMapJoin<L, K, V, S>) super.on( restrictions );
}
@Override
public SqmTreatedMapJoin<L, K, V, S> on(Predicate... restrictions) {
return (SqmTreatedMapJoin<L, K, V, S>) super.on( restrictions );
}
@Override
public SqmMapJoin<L, K, S> makeCopy(SqmCreationProcessingState creationProcessingState) {
return new SqmTreatedMapJoin<>(
wrappedPath,
treatTarget,

View File

@ -6,14 +6,25 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.query.criteria.JpaTreatedPath;
/**
* @param <T> The type of the treat source
* @param <S> The subtype of {@code <T>} that is the treat "target"
*
* @author Steve Ebersole
*/
public interface SqmTreatedPath<T, S extends T> extends SqmPathWrapper<T, S> {
public interface SqmTreatedPath<T, S extends T> extends JpaTreatedPath<T,S>, SqmPathWrapper<T, S> {
ManagedDomainType<S> getTreatTarget();
@Override
SqmPath<T> getWrappedPath();
@Override
<S1 extends S> SqmTreatedPath<S, S1> treatAs(Class<S1> treatJavaType);
@Override
<S1 extends S> SqmTreatedPath<S, S1> treatAs(EntityDomainType<S1> treatTarget);
}

View File

@ -15,7 +15,7 @@ import org.hibernate.spi.NavigablePath;
/**
* @author Steve Ebersole
*/
public class SqmTreatedPluralPartJoin<O,T, S extends T> extends SqmPluralPartJoin<O,S> implements SqmTreatedPath<T,S> {
public class SqmTreatedPluralPartJoin<O,T, S extends T> extends SqmPluralPartJoin<O,S> implements SqmTreatedJoin<O,T,S> {
private final SqmPluralPartJoin<O,T> wrappedPath;
private final EntityDomainType<S> treatTarget;
@ -101,6 +101,28 @@ public class SqmTreatedPluralPartJoin<O,T, S extends T> extends SqmPluralPartJoi
return treatTarget;
}
@Override
public <S1 extends S> SqmTreatedPluralPartJoin<O, S, S1> treatAs(Class<S1> treatJavaType) {
return super.treatAs( treatJavaType );
}
@Override
public <S1 extends S> SqmTreatedPluralPartJoin<O, S, S1> treatAs(EntityDomainType<S1> treatTarget) {
return (SqmTreatedPluralPartJoin<O, S, S1>) super.treatAs( treatTarget );
}
@Override
public <S1 extends S> SqmTreatedPluralPartJoin<O, S, S1> treatAs(Class<S1> treatJavaType, String alias) {
return (SqmTreatedPluralPartJoin<O, S, S1>) super.treatAs( treatJavaType, alias );
}
@Override
public <S1 extends S> SqmTreatedPluralPartJoin<O, S, S1> treatAs(EntityDomainType<S1> treatTarget, String alias) {
return (SqmTreatedPluralPartJoin<O, S, S1>) super.treatAs( treatTarget, alias );
}
@Override
public void appendHqlString(StringBuilder sb) {
sb.append( "treat(" );

View File

@ -9,16 +9,22 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.mapping.CollectionPart;
import org.hibernate.metamodel.model.domain.TreatableDomainType;
import org.hibernate.metamodel.model.domain.SetPersistentAttribute;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public class SqmTreatedSetJoin<O,T, S extends T> extends SqmSetJoin<O,S> implements SqmTreatedPath<T,S> {
public class SqmTreatedSetJoin<O,T, S extends T> extends SqmSetJoin<O,S> implements SqmTreatedAttributeJoin<O,T,S> {
private final SqmSetJoin<O,T> wrappedPath;
private final TreatableDomainType<S> treatTarget;
@ -128,4 +134,24 @@ public class SqmTreatedSetJoin<O,T, S extends T> extends SqmSetJoin<O,S> impleme
sb.append( treatTarget.getTypeName() );
sb.append( ')' );
}
@Override
public SqmTreatedSetJoin<O, T, S> on(JpaExpression<Boolean> restriction) {
return (SqmTreatedSetJoin<O, T, S>) super.on( restriction );
}
@Override
public SqmTreatedSetJoin<O, T, S> on(Expression<Boolean> restriction) {
return (SqmTreatedSetJoin<O, T, S>) super.on( restriction );
}
@Override
public SqmTreatedSetJoin<O, T, S> on(JpaPredicate... restrictions) {
return (SqmTreatedSetJoin<O, T, S>) super.on( restrictions );
}
@Override
public SqmTreatedSetJoin<O, T, S> on(Predicate... restrictions) {
return (SqmTreatedSetJoin<O, T, S>) super.on( restrictions );
}
}

View File

@ -6,18 +6,25 @@
*/
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.TreatableDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public class SqmTreatedSingularJoin<O,T, S extends T> extends SqmSingularJoin<O,S> implements SqmTreatedPath<T,S> {
public class SqmTreatedSingularJoin<O,T, S extends T> extends SqmSingularJoin<O,S> implements SqmTreatedAttributeJoin<O,T,S> {
private final SqmSingularJoin<O,T> wrappedPath;
private final TreatableDomainType<S> treatTarget;
@ -128,4 +135,44 @@ public class SqmTreatedSingularJoin<O,T, S extends T> extends SqmSingularJoin<O,
sb.append( treatTarget.getTypeName() );
sb.append( ')' );
}
@Override
public <S1 extends S> SqmTreatedSingularJoin<O, S, S1> treatAs(Class<S1> treatJavaType) {
return (SqmTreatedSingularJoin<O, S, S1>) super.treatAs( treatJavaType );
}
@Override
public <S1 extends S> SqmTreatedSingularJoin<O, S, S1> treatAs(EntityDomainType<S1> treatTarget) {
return (SqmTreatedSingularJoin<O, S, S1>) super.treatAs( treatTarget );
}
@Override
public <S1 extends S> SqmTreatedSingularJoin<O, S, S1> treatAs(Class<S1> treatJavaType, String alias) {
return (SqmTreatedSingularJoin<O, S, S1>) super.treatAs( treatJavaType, alias );
}
@Override
public <S1 extends S> SqmTreatedSingularJoin<O, S, S1> treatAs(EntityDomainType<S1> treatTarget, String alias) {
return (SqmTreatedSingularJoin<O, S, S1>) super.treatAs( treatTarget, alias );
}
@Override
public SqmTreatedSingularJoin<O,T,S> on(JpaExpression<Boolean> restriction) {
return (SqmTreatedSingularJoin<O, T, S>) super.on( restriction );
}
@Override
public SqmTreatedSingularJoin<O,T,S> on(JpaPredicate... restrictions) {
return (SqmTreatedSingularJoin<O, T, S>) super.on( restrictions );
}
@Override
public SqmTreatedSingularJoin<O,T,S> on(Expression<Boolean> restriction) {
return (SqmTreatedSingularJoin<O, T, S>) super.on( restriction );
}
@Override
public SqmTreatedSingularJoin<O,T,S> on(Predicate... restrictions) {
return (SqmTreatedSingularJoin<O, T, S>) super.on( restrictions );
}
}

View File

@ -9,20 +9,24 @@ package org.hibernate.query.sqm.tree.from;
import org.hibernate.Internal;
import org.hibernate.Remove;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaFetch;
import org.hibernate.query.criteria.JpaJoin;
import org.hibernate.query.criteria.JpaJoinedFrom;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* Models a join based on a mapped attribute reference.
*
* @author Steve Ebersole
*/
public interface SqmAttributeJoin<O,T> extends SqmQualifiedJoin<O,T>, JpaFetch<O,T>, JpaJoinedFrom<O,T>, JpaJoin<O,T> {
public interface SqmAttributeJoin<O,T> extends SqmJoin<O,T>, JpaFetch<O,T>, JpaJoin<O,T> {
@Override
SqmFrom<?,O> getLhs();
@ -48,21 +52,44 @@ public interface SqmAttributeJoin<O,T> extends SqmQualifiedJoin<O,T>, JpaFetch<O
void setJoinPredicate(SqmPredicate predicate);
@Override
<S extends T> SqmAttributeJoin<O, S> treatAs(Class<S> treatJavaType);
default SqmJoin<O, T> on(JpaExpression<Boolean> restriction) {
return SqmJoin.super.on( restriction );
}
@Override
<S extends T> SqmAttributeJoin<O, S> treatAs(Class<S> treatJavaType, String alias);
default SqmJoin<O, T> on(Expression<Boolean> restriction) {
return SqmJoin.super.on( restriction );
}
@Override
<S extends T> SqmAttributeJoin<O, S> treatAs(EntityDomainType<S> treatTarget);
default SqmJoin<O, T> on(JpaPredicate... restrictions) {
return SqmJoin.super.on( restrictions );
}
@Override
<S extends T> SqmAttributeJoin<O, S> treatAs(EntityDomainType<S> treatTarget, String alias);
default SqmJoin<O, T> on(Predicate... restrictions) {
return SqmJoin.super.on( restrictions );
}
@Override
<S extends T> SqmTreatedAttributeJoin<O,T,S> treatAs(Class<S> treatJavaType);
@Override
<S extends T> SqmTreatedAttributeJoin<O,T,S> treatAs(Class<S> treatJavaType, String alias);
@Override
<S extends T> SqmTreatedAttributeJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget);
@Override
<S extends T> SqmTreatedAttributeJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget, String alias);
<S extends T> SqmTreatedAttributeJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget, String alias, boolean fetch);
<S extends T> SqmTreatedAttributeJoin<O,T,S> treatAs(Class<S> treatTarget, String alias, boolean fetch);
/*
@deprecated not used anymore
*/
@Deprecated
@Remove
SqmAttributeJoin makeCopy( SqmCreationProcessingState creationProcessingState );
SqmAttributeJoin<O,T> makeCopy( SqmCreationProcessingState creationProcessingState );
}

View File

@ -7,6 +7,7 @@
package org.hibernate.query.sqm.tree.from;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.query.criteria.JpaCrossJoin;
import org.hibernate.query.hql.spi.SqmCreationProcessingState;
import org.hibernate.query.hql.spi.SqmPathRegistry;
@ -15,17 +16,36 @@ import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
import org.hibernate.query.sqm.tree.domain.SqmCorrelatedCrossJoin;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedCrossJoin;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.query.sqm.tree.predicate.SqmPredicateCollection;
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.JoinType;
import static org.hibernate.query.sqm.spi.SqmCreationHelper.buildRootNavigablePath;
/**
* Stuff and things
*
* @apiNote {@linkplain SqmCrossJoin} and its offspring are largely de-typed to account
* for {@linkplain SqmCrossJoin} having only one type argument for the right-hand
* side. To properly handle the type parameters in the hierarchy we would need to
* change this to accept type parameter for the left-handle side as well.
* <p/>
* Another option is to not make it a join as in `SqmJoin`. Instead, model it
* as a root with its predicate(s) added to an internal `SqmPredicateCollection` (ansi join predicate)
* or to the query where clause (theta joins).
*
* @implNote IMPL NOTE
*
* @author Steve Ebersole
*/
public class SqmCrossJoin<T> extends AbstractSqmFrom<T, T> implements JpaCrossJoin<T>, SqmJoin<T, T> {
private final SqmRoot<?> sqmRoot;
private final SqmPredicateCollection sqmJoinPredicates;
public SqmCrossJoin(
EntityDomainType<T> joinedEntityDescriptor,
@ -52,6 +72,7 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T, T> implements JpaCrossJo
sqmRoot.nodeBuilder()
);
this.sqmRoot = sqmRoot;
this.sqmJoinPredicates = new SqmWhereClause( nodeBuilder() );
}
@Override
@ -59,6 +80,16 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T, T> implements JpaCrossJo
return true;
}
@Override
public JoinType getJoinType() {
return null;
}
@Override
public SqmJoinType getSqmJoinType() {
return SqmJoinType.CROSS;
}
@Override
public SqmCrossJoin<T> copy(SqmCopyContext context) {
final SqmCrossJoin<T> existing = context.getCopy( this );
@ -83,7 +114,7 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T, T> implements JpaCrossJo
}
@Override
public SqmPath<?> getLhs() {
public SqmFrom<?, T> getLhs() {
// a cross-join has no LHS
return null;
}
@ -97,11 +128,6 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T, T> implements JpaCrossJo
return getReferencedPathSource().getHibernateEntityName();
}
@Override
public SqmJoinType getSqmJoinType() {
return SqmJoinType.CROSS;
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitCrossJoin( this );
@ -117,36 +143,6 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T, T> implements JpaCrossJo
return new SqmCorrelatedCrossJoin<>( this );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA
@Override
public <S extends T> SqmJoin<T, S> treatAs(Class<S> treatTarget) {
return treatAs( nodeBuilder().getDomainModel().entity( treatTarget ) );
}
@Override
public <S extends T> SqmJoin<T, S> treatAs(EntityDomainType<S> treatTarget) {
final SqmJoin<T, S> treat = findTreat( treatTarget, null );
if ( treat == null ) {
//noinspection unchecked
return addTreat( (SqmJoin<T, S>) new SqmTreatedCrossJoin<>( this, treatTarget, null ) );
}
return treat;
}
@Override
public <S extends T> SqmJoin<T, S> treatAs(Class<S> treatJavaType, String alias) {
throw new UnsupportedOperationException( "Cross join treats can not be aliased" );
}
@Override
public <S extends T> SqmJoin<T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
throw new UnsupportedOperationException( "Cross join treats can not be aliased" );
}
public SqmCrossJoin<T> makeCopy(SqmCreationProcessingState creationProcessingState) {
final SqmPathRegistry pathRegistry = creationProcessingState.getPathRegistry();
return new SqmCrossJoin<>(
@ -155,4 +151,53 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T, T> implements JpaCrossJo
pathRegistry.findFromByPath( getRoot().getNavigablePath() )
);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA
@Override
public PersistentAttribute<? super T, ?> getAttribute() {
return null;
}
@Override
public SqmPredicate getJoinPredicate() {
return sqmJoinPredicates.getPredicate();
}
@Override
public void setJoinPredicate(SqmPredicate predicate) {
sqmJoinPredicates.setPredicate( predicate );
}
@Override
public From<?, T> getParent() {
return getLhs();
}
@SuppressWarnings("unchecked")
@Override
public <S extends T> SqmTreatedCrossJoin treatAs(Class<S> treatJavaType, String alias) {
throw new UnsupportedOperationException( "Cross join treats can not be aliased" );
}
@SuppressWarnings("unchecked")
@Override
public <S extends T> SqmTreatedCrossJoin treatAs(EntityDomainType<S> treatTarget, String alias) {
throw new UnsupportedOperationException( "Cross join treats can not be aliased" );
}
@SuppressWarnings("unchecked")
@Override
public <S extends T> SqmTreatedCrossJoin treatAs(Class<S> treatAsType) {
return treatAs( treatAsType, null );
}
@SuppressWarnings("unchecked")
@Override
public <S extends T> SqmTreatedCrossJoin treatAs(EntityDomainType<S> treatAsType) {
return treatAs( treatAsType, null );
}
}

View File

@ -9,33 +9,32 @@ package org.hibernate.query.sqm.tree.from;
import org.hibernate.Incubating;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.query.criteria.JpaJoinedFrom;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
import org.hibernate.query.sqm.tree.domain.AbstractSqmQualifiedJoin;
import org.hibernate.query.sqm.tree.domain.AbstractSqmJoin;
import org.hibernate.query.sqm.tree.domain.SqmCorrelatedEntityJoin;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedJoin;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.JoinType;
/**
* @author Christian Beikov
*/
@Incubating
public class SqmCteJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements JpaJoinedFrom<T, T> {
public class SqmCteJoin<T> extends AbstractSqmJoin<T, T> {
private final SqmCteStatement<T> cte;
public SqmCteJoin(
SqmCteStatement<T> cte,
String alias,
SqmJoinType joinType,
SqmRoot<?> sqmRoot) {
SqmRoot<T> sqmRoot) {
//noinspection unchecked
this(
SqmCreationHelper.buildRootNavigablePath( "<<cte>>", alias ),
cte,
@ -52,7 +51,7 @@ public class SqmCteJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements Jpa
SqmPathSource<T> pathSource,
String alias,
SqmJoinType joinType,
SqmRoot<?> sqmRoot) {
SqmRoot<T> sqmRoot) {
super(
navigablePath,
pathSource,
@ -75,6 +74,7 @@ public class SqmCteJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements Jpa
if ( existing != null ) {
return existing;
}
//noinspection unchecked
final SqmCteJoin<T> path = context.registerCopy(
this,
new SqmCteJoin<>(
@ -83,7 +83,7 @@ public class SqmCteJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements Jpa
getReferencedPathSource(),
getExplicitAlias(),
getSqmJoinType(),
findRoot().copy( context )
(SqmRoot<T>) findRoot().copy( context )
)
);
copyTo( path, context );
@ -104,7 +104,7 @@ public class SqmCteJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements Jpa
}
@Override
public SqmPath<?> getLhs() {
public SqmFrom<?,T> getLhs() {
// A cte-join has no LHS
return null;
}
@ -128,17 +128,17 @@ public class SqmCteJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements Jpa
}
@Override
public <S extends T> SqmQualifiedJoin<T, S> treatAs(Class<S> treatJavaType, String alias) {
public <S extends T> SqmTreatedJoin<T, T, S> treatAs(Class<S> treatJavaType, String alias) {
throw new UnsupportedOperationException( "CTE joins can not be treated" );
}
@Override
public <S extends T> SqmQualifiedJoin<T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
public <S extends T> SqmTreatedJoin<T, T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
throw new UnsupportedOperationException( "CTE joins can not be treated" );
}
@Override
public From<?, T> getParent() {
public SqmFrom<?, T> getParent() {
return getCorrelationParent();
}

View File

@ -18,14 +18,13 @@ import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.AbstractSqmQualifiedJoin;
import org.hibernate.query.sqm.tree.domain.AbstractSqmJoin;
import org.hibernate.query.sqm.tree.domain.SqmCorrelatedEntityJoin;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedJoin;
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Predicate;
@ -33,7 +32,7 @@ import jakarta.persistence.criteria.Predicate;
* @author Christian Beikov
*/
@Incubating
public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements JpaDerivedJoin<T> {
public class SqmDerivedJoin<T> extends AbstractSqmJoin<T, T> implements JpaDerivedJoin<T> {
private final SqmSubQuery<T> subQuery;
private final boolean lateral;
@ -42,7 +41,7 @@ public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements
String alias,
SqmJoinType joinType,
boolean lateral,
SqmRoot<?> sqmRoot) {
SqmRoot<T> sqmRoot) {
this(
SqmCreationHelper.buildRootNavigablePath( "<<derived>>", alias ),
subQuery,
@ -61,7 +60,7 @@ public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements
SqmPathSource<T> pathSource,
String alias,
SqmJoinType joinType,
SqmRoot<?> sqmRoot) {
SqmRoot<T> sqmRoot) {
super(
navigablePath,
pathSource,
@ -98,6 +97,7 @@ public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements
if ( existing != null ) {
return existing;
}
//noinspection unchecked
final SqmDerivedJoin<T> path = context.registerCopy(
this,
new SqmDerivedJoin<>(
@ -107,7 +107,7 @@ public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements
getReferencedPathSource(),
getExplicitAlias(),
getSqmJoinType(),
findRoot().copy( context )
(SqmRoot<T>) findRoot().copy( context )
)
);
copyTo( path, context );
@ -134,7 +134,7 @@ public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements
}
@Override
public SqmPath<?> getLhs() {
public SqmFrom<?,T> getLhs() {
// A derived-join has no LHS
return null;
}
@ -173,22 +173,22 @@ public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements
}
@Override
public <S extends T> SqmCorrelatedEntityJoin<T, S> treatAs(Class<S> treatAsType) {
public <S extends T> SqmTreatedJoin<T, T, S> treatAs(Class<S> treatTarget) {
throw new UnsupportedOperationException( "Derived joins can not be treated" );
}
@Override
public <S extends T> SqmCorrelatedEntityJoin<T, S> treatAs(EntityDomainType<S> treatAsType) {
public <S extends T> SqmTreatedJoin<T, T, S> treatAs(EntityDomainType<S> treatTarget) {
throw new UnsupportedOperationException( "Derived joins can not be treated" );
}
@Override
public <S extends T> SqmCorrelatedEntityJoin<T, S> treatAs(Class<S> treatJavaType, String alias) {
public <S extends T> SqmTreatedJoin<T, T, S> treatAs(Class<S> treatJavaType, String alias) {
throw new UnsupportedOperationException( "Derived joins can not be treated" );
}
@Override
public <S extends T> SqmCorrelatedEntityJoin<T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
public <S extends T> SqmTreatedJoin<T, T, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
throw new UnsupportedOperationException( "Derived joins can not be treated" );
}
@ -199,9 +199,9 @@ public class SqmDerivedJoin<T> extends AbstractSqmQualifiedJoin<T, T> implements
}
@Override
public From<?, T> getParent() {
public SqmFrom<?, T> getParent() {
//noinspection unchecked
return (From<?, T>) getRoot();
return (SqmFrom<?, T>) getRoot();
}
@Override

View File

@ -18,7 +18,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.spi.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.AbstractSqmQualifiedJoin;
import org.hibernate.query.sqm.tree.domain.AbstractSqmJoin;
import org.hibernate.query.sqm.tree.domain.SqmCorrelatedEntityJoin;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedEntityJoin;
@ -26,7 +26,6 @@ import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.spi.NavigablePath;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.metamodel.EntityType;
@ -34,7 +33,7 @@ import jakarta.persistence.metamodel.EntityType;
/**
* @author Steve Ebersole
*/
public class SqmEntityJoin<L,R> extends AbstractSqmQualifiedJoin<L,R> implements JpaEntityJoin<L,R> {
public class SqmEntityJoin<L,R> extends AbstractSqmJoin<L,R> implements JpaEntityJoin<L,R> {
private final SqmRoot<L> sqmRoot;
public SqmEntityJoin(
@ -99,7 +98,7 @@ public class SqmEntityJoin<L,R> extends AbstractSqmQualifiedJoin<L,R> implements
}
@Override
public From<?, L> getParent() {
public SqmFrom<?, L> getParent() {
return getRoot();
}
@ -127,7 +126,7 @@ public class SqmEntityJoin<L,R> extends AbstractSqmQualifiedJoin<L,R> implements
}
@Override
public SqmPath<?> getLhs() {
public SqmFrom<?,L> getLhs() {
// An entity-join has no LHS
return null;
}
@ -184,26 +183,13 @@ public class SqmEntityJoin<L,R> extends AbstractSqmQualifiedJoin<L,R> implements
return treat;
}
// @Override
// public <S extends T> SqmTreatedEntityJoin<T,S> treatAs(Class<S> treatJavaType) throws PathException {
// return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
// }
// @Override
// public <S extends T> SqmTreatedEntityJoin<T,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
// final SqmTreatedEntityJoin<T,S> treat = findTreat( treatTarget, null );
// if ( treat == null ) {
// return addTreat( new SqmTreatedEntityJoin<>( this, treatTarget, null ) );
// }
// return treat;
// }
@Override
public <S extends R> SqmEntityJoin<L,S> treatAs(Class<S> treatJavaType, String alias) {
public <S extends R> SqmTreatedEntityJoin<L,R,S> treatAs(Class<S> treatJavaType, String alias) {
throw new UnsupportedOperationException( "Entity join treats can not be aliased" );
}
@Override
public <S extends R> SqmEntityJoin<L,S> treatAs(EntityDomainType<S> treatTarget, String alias) {
public <S extends R> SqmTreatedEntityJoin<L,R,S> treatAs(EntityDomainType<S> treatTarget, String alias) {
throw new UnsupportedOperationException( "Entity join treats can not be aliased" );
}

View File

@ -27,6 +27,7 @@ import org.hibernate.query.sqm.tree.domain.SqmMapJoin;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmSetJoin;
import org.hibernate.query.sqm.tree.domain.SqmSingularJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedFrom;
import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty;
@ -68,21 +69,22 @@ public interface SqmFrom<L, R> extends SqmVisitableNode, SqmPath<R>, JpaFrom<L,
/**
* The treats associated with this SqmFrom
*/
List<SqmFrom<?, ?>> getSqmTreats();
List<SqmTreatedFrom<?,?,?>> getSqmTreats();
default boolean hasTreats() {
return !isEmpty( getSqmTreats() );
}
@Override
<S extends R> SqmFrom<L, S> treatAs(Class<S> treatAsType);
<S extends R> SqmTreatedFrom<L,R,S> treatAs(Class<S> treatJavaType);
@Override
<S extends R> SqmFrom<L, S> treatAs(EntityDomainType<S> treatAsType);
<S extends R> SqmTreatedFrom<L,R,S> treatAs(EntityDomainType<S> treatTarget);
<S extends R> SqmFrom<L, S> treatAs(Class<S> treatJavaType, String alias);
<S extends R> SqmTreatedFrom<L,R,S> treatAs(Class<S> treatJavaType, String alias);
<S extends R> SqmTreatedFrom<L,R,S> treatAs(EntityDomainType<S> treatTarget, String alias);
<S extends R> SqmFrom<L, S> treatAs(EntityDomainType<S> treatTarget, String alias);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA

View File

@ -135,10 +135,8 @@ public class SqmFromClause implements Serializable {
sb.append( " cross join " );
break;
}
if ( sqmJoin instanceof SqmAttributeJoin<?, ?> ) {
final SqmAttributeJoin<?, ?> attributeJoin = (SqmAttributeJoin<?, ?>) sqmJoin;
if ( sqmFrom instanceof SqmTreatedPath<?, ?> ) {
final SqmTreatedPath<?, ?> treatedPath = (SqmTreatedPath<?, ?>) sqmFrom;
if ( sqmJoin instanceof SqmAttributeJoin<?, ?> attributeJoin ) {
if ( sqmFrom instanceof SqmTreatedPath<?, ?> treatedPath ) {
sb.append( "treat(" );
sb.append( treatedPath.getWrappedPath().resolveAlias() );
sb.append( " as " ).append( treatedPath.getTreatTarget().getTypeName() ).append( ')' );
@ -159,8 +157,7 @@ public class SqmFromClause implements Serializable {
sb.append( ' ' ).append( sqmJoin.resolveAlias() );
appendJoins( sqmJoin, sb );
}
else if ( sqmJoin instanceof SqmEntityJoin<?> ) {
final SqmEntityJoin<?> sqmEntityJoin = (SqmEntityJoin<?>) sqmJoin;
else if ( sqmJoin instanceof SqmEntityJoin<?, ?> sqmEntityJoin ) {
sb.append( ( sqmEntityJoin ).getEntityName() );
sb.append( ' ' ).append( sqmJoin.resolveAlias() );
if ( sqmEntityJoin.getJoinPredicate() != null ) {

View File

@ -6,16 +6,25 @@
*/
package org.hibernate.query.sqm.tree.from;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.Predicate;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaJoin;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.SqmTreatedJoin;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import static org.hibernate.query.sqm.spi.SqmCreationHelper.combinePredicates;
/**
* @author Steve Ebersole
*/
public interface SqmJoin<L, R> extends SqmFrom<L, R> {
public interface SqmJoin<L, R> extends SqmFrom<L, R>, JpaJoin<L,R> {
/**
* The type of join - inner, cross, etc
*/
@ -26,6 +35,20 @@ public interface SqmJoin<L, R> extends SqmFrom<L, R> {
*/
boolean isImplicitlySelectable();
/**
* Obtain the join predicate
*
* @return The join predicate
*/
SqmPredicate getJoinPredicate();
/**
* Inject the join predicate
*
* @param predicate The join predicate
*/
void setJoinPredicate(SqmPredicate predicate);
@Override
<X, Y> SqmAttributeJoin<X, Y> join(String attributeName);
@ -36,14 +59,55 @@ public interface SqmJoin<L, R> extends SqmFrom<L, R> {
SqmJoin<L, R> copy(SqmCopyContext context);
@Override
<S extends R> SqmJoin<L, S> treatAs(Class<S> treatAsType);
<S extends R> SqmTreatedJoin<L,R,S> treatAs(Class<S> treatAsType);
@Override
<S extends R> SqmJoin<L, S> treatAs(EntityDomainType<S> treatAsType);
<S extends R> SqmTreatedJoin<L,R,S> treatAs(EntityDomainType<S> treatAsType);
@Override
<S extends R> SqmJoin<L, S> treatAs(Class<S> treatJavaType, String alias);
<S extends R> SqmTreatedJoin<L,R,S> treatAs(Class<S> treatJavaType, String alias);
@Override
<S extends R> SqmJoin<L, S> treatAs(EntityDomainType<S> treatTarget, String alias);
<S extends R> SqmTreatedJoin<L,R,S> treatAs(EntityDomainType<S> treatTarget, String alias);
@Override
default SqmPredicate getOn() {
return getJoinPredicate();
}
@Override
default SqmJoin<L, R> on(JpaExpression<Boolean> restriction) {
setJoinPredicate( combinePredicates(
getJoinPredicate(),
getJoinPredicate().nodeBuilder().wrap( restriction )
) );
return this;
}
@Override
default SqmJoin<L, R> on(Expression<Boolean> restriction) {
setJoinPredicate( combinePredicates(
getJoinPredicate(),
getJoinPredicate().nodeBuilder().wrap( restriction )
) );
return this;
}
@Override
default SqmJoin<L, R> on(JpaPredicate... restrictions) {
setJoinPredicate( combinePredicates(
getJoinPredicate(),
restrictions
) );
return this;
}
@Override
default SqmJoin<L, R> on(Predicate... restrictions) {
setJoinPredicate( combinePredicates(
getJoinPredicate(),
restrictions
) );
return this;
}
}

View File

@ -1,44 +0,0 @@
/*
* 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.sqm.tree.from;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaJoinedFrom;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
/**
* Common contract for qualified/restricted/predicated joins.
*
* @author Steve Ebersole
*/
public interface SqmQualifiedJoin<L, R> extends SqmJoin<L,R>, JpaJoinedFrom<L,R> {
/**
* Obtain the join predicate
*
* @return The join predicate
*/
SqmPredicate getJoinPredicate();
/**
* Inject the join predicate
*
* @param predicate The join predicate
*/
void setJoinPredicate(SqmPredicate predicate);
@Override
<S extends R> SqmQualifiedJoin<L, S> treatAs(Class<S> treatAsType);
@Override
<S extends R> SqmQualifiedJoin<L, S> treatAs(EntityDomainType<S> treatAsType);
@Override
<S extends R> SqmQualifiedJoin<L, S> treatAs(Class<S> treatJavaType, String alias);
@Override
<S extends R> SqmQualifiedJoin<L, S> treatAs(EntityDomainType<S> treatTarget, String alias);
}

View File

@ -11,6 +11,7 @@ import java.util.List;
import org.hibernate.Internal;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.tree.domain.SqmTreatedFrom;
import org.hibernate.spi.NavigablePath;
import org.hibernate.query.PathException;
import org.hibernate.query.criteria.JpaRoot;
@ -191,27 +192,27 @@ public class SqmRoot<E> extends AbstractSqmFrom<E,E> implements JpaRoot<E> {
}
@Override
public <S extends E> SqmFrom<E, S> treatAs(Class<S> treatJavaType) throws PathException {
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
public <S extends E> SqmTreatedFrom<E,E,S> treatAs(Class<S> treatJavaType) throws PathException {
return (SqmTreatedFrom<E, E, S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends E> SqmFrom<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
final SqmFrom<E, S> treat = findTreat( treatTarget, null );
public <S extends E> SqmTreatedFrom<E,E,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
final SqmTreatedFrom<E,E,S> treat = findTreat( treatTarget, null );
if ( treat == null ) {
//noinspection rawtypes,unchecked
return addTreat( new SqmTreatedRoot( this, treatTarget ) );
return addTreat( (SqmTreatedFrom) new SqmTreatedRoot( this, treatTarget ) );
}
return treat;
}
@Override
public <S extends E> SqmFrom<E, S> treatAs(Class<S> treatJavaType, String alias) {
public <S extends E> SqmTreatedFrom<E,E,S> treatAs(Class<S> treatJavaType, String alias) {
throw new UnsupportedOperationException( "Root treats can not be aliased" );
}
@Override
public <S extends E> SqmFrom<E, S> treatAs(EntityDomainType<S> treatTarget, String alias) {
public <S extends E> SqmTreatedFrom<E,E,S> treatAs(EntityDomainType<S> treatTarget, String alias) {
throw new UnsupportedOperationException( "Root treats can not be aliased" );
}

View File

@ -0,0 +1,48 @@
/*
* 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.sqm.tree.from;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.domain.SqmTreatedJoin;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
/**
* @author Steve Ebersole
*/
public interface SqmTreatedAttributeJoin<L,R,R1 extends R> extends SqmAttributeJoin<L,R1>, SqmTreatedJoin<L,R,R1> {
@Override
<S extends R1> SqmTreatedAttributeJoin<L,R1,S> treatAs(Class<S> treatJavaType);
@Override
<S extends R1> SqmTreatedAttributeJoin<L,R1,S> treatAs(Class<S> treatJavaType, String alias);
@Override
<S extends R1> SqmTreatedAttributeJoin<L,R1,S> treatAs(EntityDomainType<S> treatTarget);
@Override
<S extends R1> SqmTreatedAttributeJoin<L,R1,S> treatAs(EntityDomainType<S> treatTarget, String alias);
@Override
SqmTreatedAttributeJoin<L,R,R1> on(JpaExpression<Boolean> restriction);
@Override
SqmTreatedAttributeJoin<L,R,R1> on(Expression<Boolean> restriction);
@Override
SqmTreatedAttributeJoin<L,R,R1> on(JpaPredicate... restrictions);
@Override
SqmTreatedAttributeJoin<L,R,R1> on(Predicate... restrictions);
@Override
SqmTreatedAttributeJoin<L,R,R1> copy(SqmCopyContext context);
}

View File

@ -0,0 +1,26 @@
/*
* 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.sqm.tree.predicate;
import java.util.Collection;
/**
* A grouping of predicates, such as a where-clause, join restriction, ...
*
* @author Steve Ebersole
*/
public interface SqmPredicateCollection {
SqmPredicate getPredicate();
void setPredicate(SqmPredicate predicate);
void applyPredicate(SqmPredicate predicate);
void applyPredicates(SqmPredicate... predicates);
void applyPredicates(Collection<SqmPredicate> predicates);
}

View File

@ -14,7 +14,7 @@ import org.hibernate.query.sqm.tree.SqmCopyContext;
/**
* @author Steve Ebersole
*/
public class SqmWhereClause {
public class SqmWhereClause implements SqmPredicateCollection {
private final NodeBuilder nodeBuilder;
private SqmPredicate predicate;
@ -35,14 +35,17 @@ public class SqmWhereClause {
);
}
@Override
public SqmPredicate getPredicate() {
return predicate;
}
@Override
public void setPredicate(SqmPredicate predicate) {
this.predicate = predicate;
}
@Override
public void applyPredicate(SqmPredicate predicate) {
if ( this.predicate == null ) {
this.predicate = predicate;
@ -52,12 +55,14 @@ public class SqmWhereClause {
}
}
@Override
public void applyPredicates(SqmPredicate... predicates) {
for ( SqmPredicate sqmPredicate : predicates ) {
applyPredicate( sqmPredicate );
}
}
@Override
public void applyPredicates(Collection<SqmPredicate> predicates) {
for ( SqmPredicate sqmPredicate : predicates ) {
applyPredicate( sqmPredicate );

View File

@ -16,6 +16,8 @@ import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator;
import java.util.HashMap;
import java.util.Map;
import jakarta.persistence.SchemaValidationException;
/**
* Implementation of {@link SchemaManager}, backed by a {@link SessionFactoryImplementor}
* and {@link SchemaManagementToolCoordinator}.
@ -88,4 +90,13 @@ public class SchemaManagerImpl implements SchemaManager {
);
}
@Override
public void validate() throws SchemaValidationException {
validateMappedObjects();
}
@Override
public void truncate() {
truncateMappedObjects();
}
}

View File

@ -4380,7 +4380,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
@Override
public void visitSortSpecification(SortSpecification sortSpecification) {
final Expression sortExpression = sortSpecification.getSortExpression();
final NullPrecedence nullPrecedence = sortSpecification.getNullPrecedence();
final NullPrecedence nullPrecedence = sortSpecification.getHibernateNullPrecedence();
final SortDirection sortOrder = sortSpecification.getSortOrder();
final boolean ignoreCase = sortSpecification.isIgnoreCase();
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( sortExpression );

View File

@ -1,20 +1,32 @@
= 6.6 Migration Guide
= 7.0 Migration Guide
:toc:
:toclevels: 4
:docsBase: https://docs.jboss.org/hibernate/orm
:versionDocBase: {docsBase}/6.6
:versionDocBase: {docsBase}/6.4
:userGuideBase: {versionDocBase}/userguide/html_single/Hibernate_User_Guide.html
:javadocsBase: {versionDocBase}/javadocs
This guide discusses migration to Hibernate ORM version 6.6. For migration from
This guide discusses migration to Hibernate ORM version 7.0. For migration from
earlier versions, see any other pertinent migration guides as well.
* link:{docsBase}/6.5/migration-guide/migration-guide.html[6.5 Migration guide]
* link:{docsBase}/6.4/migration-guide/migration-guide.html[6.4 Migration guide]
* link:{docsBase}/6.3/migration-guide/migration-guide.html[6.3 Migration guide]
* link:{docsBase}/6.2/migration-guide/migration-guide.html[6.2 Migration guide]
* link:{docsBase}/6.1/migration-guide/migration-guide.html[6.1 Migration guide]
* link:{docsBase}/6.0/migration-guide/migration-guide.html[6.0 Migration guide]
[[jpa-32]]
== JPA 3.2
7.0 migrates to JPA 3.2 which is fairly disruptive, mainly around:
* type parameters
* Affects much of the Criteria API - especially roots, joins, paths
* Affects much of the Graph API
* new JPA features colliding with previous Hibernate extension features
* `Nulls` (JPA) v. `NullPrecedence` (Hibernate), including JPA's new `Order#getNullPrecedence()` returning `Nulls`
colliding with Hibernate's `SqmSortSpecification#getNullPrecedence` returning `NullPrecedence`. Hibernate's form
was renamed to `SqmSortSpecification#getHibernateNullPrecedence` to avoid the collision.
* `SchemaManager` is now also a JPA contract exposed as `EntityManagerFactory#getSchemaManager` which leads to type issues for
Hibernate's `SessionFactory#getSchemaManager`. Hibernate's `SchemaManager` now extends the new JPA `SchemaManager`.
But that is a bytecode incompatibility.
* JPA has added support in its Graph API for things Hibernate has supported for some time. Some of those are collisions
requiring changes to the Hibernate API.
[[oracle-implicit-array-types]]
== Oracle implicit array types