Skip to content

Commit

Permalink
HHH-19126 Correct plural attribute path to be collection-typed
Browse files Browse the repository at this point in the history
  • Loading branch information
mbladel committed Feb 14, 2025
1 parent cf6359d commit d852e03
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,12 @@ public Class<E> getBindableJavaType() {
return getElementType().getJavaType();
}

@SuppressWarnings("unchecked")
@Override
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
return new SqmPluralValuedSimplePath<>(
// We need an unchecked cast here : PluralPersistentAttribute implements path source with its element type
// but resolving paths from it must produce collection-typed expressions.
return (SqmPath<E>) new SqmPluralValuedSimplePath<>(
PathHelper.append( lhs, this, intermediatePathSource ),
this,
lhs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,55 @@
import org.hibernate.query.hql.spi.SqmPathRegistry;
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.expression.SqmExpression;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;

/**
* An SqmPath for plural attribute paths
*
* @param <E> The collection element type, which is the "bindable" type in the SQM tree
* @param <C> The collection type
*
* @author Steve Ebersole
*/
public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
public class SqmPluralValuedSimplePath<C> extends AbstractSqmSimplePath<C> {
public SqmPluralValuedSimplePath(
NavigablePath navigablePath,
PluralPersistentAttribute<?, ?, E> referencedNavigable,
PluralPersistentAttribute<?, C, ?> referencedNavigable,
SqmPath<?> lhs,
NodeBuilder nodeBuilder) {
this( navigablePath, referencedNavigable, lhs, null, nodeBuilder );
}

public SqmPluralValuedSimplePath(
NavigablePath navigablePath,
PluralPersistentAttribute<?, ?, E> referencedNavigable,
PluralPersistentAttribute<?, C, ?> referencedNavigable,
SqmPath<?> lhs,
String explicitAlias,
NodeBuilder nodeBuilder) {
super( navigablePath, referencedNavigable, lhs, explicitAlias, nodeBuilder );
// We need to do an unchecked cast here: PluralPersistentAttribute implements path source with
// the element type, but paths generated from it must be collection-typed.
//noinspection unchecked
super( navigablePath, (SqmPathSource<C>) referencedNavigable, lhs, explicitAlias, nodeBuilder );
}

@Override
public SqmPluralValuedSimplePath<E> copy(SqmCopyContext context) {
final SqmPluralValuedSimplePath<E> existing = context.getCopy( this );
public SqmPluralValuedSimplePath<C> copy(SqmCopyContext context) {
final SqmPluralValuedSimplePath<C> existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}

final SqmPath<?> lhsCopy = getLhs().copy( context );
final SqmPluralValuedSimplePath<E> path = context.registerCopy(
final SqmPluralValuedSimplePath<C> path = context.registerCopy(
this,
new SqmPluralValuedSimplePath<>(
getNavigablePathCopy( lhsCopy ),
getModel(),
(PluralPersistentAttribute<?,C,?>) getModel(),
lhsCopy,
getExplicitAlias(),
nodeBuilder()
Expand All @@ -71,19 +76,13 @@ public SqmPluralValuedSimplePath<E> copy(SqmCopyContext context) {
return path;
}

@Override
public PluralPersistentAttribute<?, ?, E> getReferencedPathSource() {
return (PluralPersistentAttribute<?, ?, E>) super.getReferencedPathSource();
}

@Override
public PluralPersistentAttribute<?, ?, E> getModel() {
return (PluralPersistentAttribute<?, ?, E>) super.getModel();
public PluralPersistentAttribute<?, C, ?> getPluralAttribute() {
return (PluralPersistentAttribute<?, C, ?>) getModel();
}

@Override
public PluralPersistentAttribute<?,?,E> getNodeType() {
return getReferencedPathSource();
public JavaType<C> getJavaTypeDescriptor() {
return getPluralAttribute().getAttributeJavaType();
}

@Override
Expand Down Expand Up @@ -125,12 +124,11 @@ public SqmPath<?> resolveIndexedAccess(
}
SqmFrom<?, ?> path = pathRegistry.findFromByPath( navigablePath.getParent() );
if ( path == null ) {
final PluralPersistentAttribute<?, ?, E> referencedPathSource = getReferencedPathSource();
final SqmPathSource<C> referencedPathSource = getReferencedPathSource();
final SqmFrom<?, Object> parent = pathRegistry.resolveFrom( getLhs() );
final SqmQualifiedJoin<Object, ?> join;
final SqmExpression<?> index;
if ( referencedPathSource instanceof ListPersistentAttribute<?, ?> ) {
//noinspection unchecked
join = new SqmListJoin<>(
parent,
(ListPersistentAttribute<Object, ?>) referencedPathSource,
Expand All @@ -142,7 +140,6 @@ public SqmPath<?> resolveIndexedAccess(
index = ( (SqmListJoin<?, ?>) join ).index();
}
else if ( referencedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
//noinspection unchecked
join = new SqmMapJoin<>(
parent,
(MapPersistentAttribute<Object, ?, ?>) referencedPathSource,
Expand Down Expand Up @@ -171,38 +168,17 @@ else if ( referencedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
}

@Override
public SqmExpression<Class<? extends E>> type() {
public SqmExpression<Class<? extends C>> type() {
throw new UnsupportedOperationException( "Cannot access the type of plural valued simple paths" );
}

@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(Class<S> treatJavaType) throws PathException {
public <S extends C> SqmTreatedPath<C, S> treatAs(Class<S> treatJavaType) throws PathException {
throw new UnsupportedOperationException( "Cannot treat plural valued simple paths" );
}

@Override
public <S extends E> SqmTreatedEntityValuedSimplePath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
public <S extends C> SqmTreatedEntityValuedSimplePath<C, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
throw new UnsupportedOperationException( "Cannot treat plural valued simple paths" );
}

// @Override
// public DomainResult createDomainResult(
// String resultVariable,
// DomainResultCreationState creationState,
// DomainResultCreationContext creationContext) {
// return new CollectionResultImpl(
// getReferencedNavigable().getPluralAttribute().getDescribedAttribute(),
// getNavigablePath(),
// resultVariable,
// LockMode.NONE,
// getReferencedNavigable().getPluralAttribute().getCollectionKeyDescriptor().createDomainResult(
// getNavigablePath().append( "{id}" ),
// null,
// creationState,
// creationContext
// ),
// initializerProducerCreator.createProducer( resultVariable, creationState, creationContext )
// );
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public SqmMemberOfPredicate(
this.pluralPath = pluralPath;
this.leftHandExpression = leftHandExpression;

final SimpleDomainType<?> simpleDomainType = pluralPath.getReferencedPathSource().getElementType();
final SimpleDomainType<?> simpleDomainType = pluralPath.getPluralAttribute().getElementType();

if ( !areTypesComparable(leftHandExpression.getNodeType(), simpleDomainType, nodeBuilder.getSessionFactory()) ) {
throw new SemanticException(
Expand Down

0 comments on commit d852e03

Please sign in to comment.