Skip to content

Commit 14b3894

Browse files
committed
HHH-19126 Correct plural attribute path to be collection-typed
1 parent e2b3925 commit 14b3894

File tree

3 files changed

+27
-48
lines changed

3 files changed

+27
-48
lines changed

hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractPluralAttribute.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,12 @@ public Class<E> getBindableJavaType() {
150150
return getElementType().getJavaType();
151151
}
152152

153+
@SuppressWarnings("unchecked")
153154
@Override
154155
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
155-
return new SqmPluralValuedSimplePath<>(
156+
// We need an unchecked cast here : PluralPersistentAttribute implements path source with its element type
157+
// but resolving paths from it must produce collection-typed expressions.
158+
return (SqmPath<E>) new SqmPluralValuedSimplePath<>(
156159
PathHelper.append( lhs, this, intermediatePathSource ),
157160
this,
158161
lhs,

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralValuedSimplePath.java

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,51 +15,56 @@
1515
import org.hibernate.query.hql.spi.SqmPathRegistry;
1616
import org.hibernate.query.sqm.NodeBuilder;
1717
import org.hibernate.query.sqm.SemanticQueryWalker;
18+
import org.hibernate.query.sqm.SqmPathSource;
1819
import org.hibernate.query.sqm.tree.SqmCopyContext;
1920
import org.hibernate.query.sqm.tree.SqmJoinType;
2021
import org.hibernate.query.sqm.tree.expression.SqmExpression;
2122
import org.hibernate.query.sqm.tree.from.SqmFrom;
2223
import org.hibernate.query.sqm.tree.from.SqmJoin;
2324
import org.hibernate.spi.NavigablePath;
25+
import org.hibernate.type.descriptor.java.JavaType;
2426

2527
/**
2628
* An SqmPath for plural attribute paths
2729
*
28-
* @param <E> The collection element type, which is the "bindable" type in the SQM tree
30+
* @param <C> The collection type
2931
*
3032
* @author Steve Ebersole
3133
*/
32-
public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
34+
public class SqmPluralValuedSimplePath<C> extends AbstractSqmSimplePath<C> {
3335
public SqmPluralValuedSimplePath(
3436
NavigablePath navigablePath,
35-
PluralPersistentAttribute<?, ?, E> referencedNavigable,
37+
PluralPersistentAttribute<?, C, ?> referencedNavigable,
3638
SqmPath<?> lhs,
3739
NodeBuilder nodeBuilder) {
3840
this( navigablePath, referencedNavigable, lhs, null, nodeBuilder );
3941
}
4042

4143
public SqmPluralValuedSimplePath(
4244
NavigablePath navigablePath,
43-
PluralPersistentAttribute<?, ?, E> referencedNavigable,
45+
PluralPersistentAttribute<?, C, ?> referencedNavigable,
4446
SqmPath<?> lhs,
4547
String explicitAlias,
4648
NodeBuilder nodeBuilder) {
47-
super( navigablePath, referencedNavigable, lhs, explicitAlias, nodeBuilder );
49+
// We need to do an unchecked cast here: PluralPersistentAttribute implements path source with
50+
// the element type, but paths generated from it must be collection-typed.
51+
//noinspection unchecked
52+
super( navigablePath, (SqmPathSource<C>) referencedNavigable, lhs, explicitAlias, nodeBuilder );
4853
}
4954

5055
@Override
51-
public SqmPluralValuedSimplePath<E> copy(SqmCopyContext context) {
52-
final SqmPluralValuedSimplePath<E> existing = context.getCopy( this );
56+
public SqmPluralValuedSimplePath<C> copy(SqmCopyContext context) {
57+
final SqmPluralValuedSimplePath<C> existing = context.getCopy( this );
5358
if ( existing != null ) {
5459
return existing;
5560
}
5661

5762
final SqmPath<?> lhsCopy = getLhs().copy( context );
58-
final SqmPluralValuedSimplePath<E> path = context.registerCopy(
63+
final SqmPluralValuedSimplePath<C> path = context.registerCopy(
5964
this,
6065
new SqmPluralValuedSimplePath<>(
6166
getNavigablePathCopy( lhsCopy ),
62-
getModel(),
67+
(PluralPersistentAttribute<?,C,?>) getModel(),
6368
lhsCopy,
6469
getExplicitAlias(),
6570
nodeBuilder()
@@ -69,19 +74,13 @@ public SqmPluralValuedSimplePath<E> copy(SqmCopyContext context) {
6974
return path;
7075
}
7176

72-
@Override
73-
public PluralPersistentAttribute<?, ?, E> getReferencedPathSource() {
74-
return (PluralPersistentAttribute<?, ?, E>) super.getReferencedPathSource();
75-
}
76-
77-
@Override
78-
public PluralPersistentAttribute<?, ?, E> getModel() {
79-
return (PluralPersistentAttribute<?, ?, E>) super.getModel();
77+
public PluralPersistentAttribute<?, C, ?> getPluralAttribute() {
78+
return (PluralPersistentAttribute<?, C, ?>) getModel();
8079
}
8180

8281
@Override
83-
public PluralPersistentAttribute<?,?,E> getNodeType() {
84-
return getReferencedPathSource();
82+
public JavaType<C> getJavaTypeDescriptor() {
83+
return getPluralAttribute().getAttributeJavaType();
8584
}
8685

8786
@Override
@@ -123,12 +122,11 @@ public SqmPath<?> resolveIndexedAccess(
123122
}
124123
SqmFrom<?, ?> path = pathRegistry.findFromByPath( navigablePath.getParent() );
125124
if ( path == null ) {
126-
final PluralPersistentAttribute<?, ?, E> referencedPathSource = getReferencedPathSource();
125+
final SqmPathSource<C> referencedPathSource = getReferencedPathSource();
127126
final SqmFrom<?, Object> parent = pathRegistry.resolveFrom( getLhs() );
128127
final SqmJoin<Object, ?> join;
129128
final SqmExpression<?> index;
130129
if ( referencedPathSource instanceof ListPersistentAttribute<?, ?> ) {
131-
//noinspection unchecked
132130
join = new SqmListJoin<>(
133131
parent,
134132
(ListPersistentAttribute<Object, ?>) referencedPathSource,
@@ -140,7 +138,6 @@ public SqmPath<?> resolveIndexedAccess(
140138
index = ( (SqmListJoin<?, ?>) join ).index();
141139
}
142140
else if ( referencedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
143-
//noinspection unchecked
144141
join = new SqmMapJoin<>(
145142
parent,
146143
(MapPersistentAttribute<Object, ?, ?>) referencedPathSource,
@@ -169,38 +166,17 @@ else if ( referencedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
169166
}
170167

171168
@Override
172-
public SqmExpression<Class<? extends E>> type() {
169+
public SqmExpression<Class<? extends C>> type() {
173170
throw new UnsupportedOperationException( "Cannot access the type of plural valued simple paths" );
174171
}
175172

176173
@Override
177-
public <S extends E> SqmTreatedPath<E, S> treatAs(Class<S> treatJavaType) throws PathException {
174+
public <S extends C> SqmTreatedPath<C, S> treatAs(Class<S> treatJavaType) throws PathException {
178175
throw new UnsupportedOperationException( "Cannot treat plural valued simple paths" );
179176
}
180177

181178
@Override
182-
public <S extends E> SqmTreatedEntityValuedSimplePath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
179+
public <S extends C> SqmTreatedEntityValuedSimplePath<C, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
183180
throw new UnsupportedOperationException( "Cannot treat plural valued simple paths" );
184181
}
185-
186-
// @Override
187-
// public DomainResult createDomainResult(
188-
// String resultVariable,
189-
// DomainResultCreationState creationState,
190-
// DomainResultCreationContext creationContext) {
191-
// return new CollectionResultImpl(
192-
// getReferencedNavigable().getPluralAttribute().getDescribedAttribute(),
193-
// getNavigablePath(),
194-
// resultVariable,
195-
// LockMode.NONE,
196-
// getReferencedNavigable().getPluralAttribute().getCollectionKeyDescriptor().createDomainResult(
197-
// getNavigablePath().append( "{id}" ),
198-
// null,
199-
// creationState,
200-
// creationContext
201-
// ),
202-
// initializerProducerCreator.createProducer( resultVariable, creationState, creationContext )
203-
// );
204-
// }
205-
206182
}

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmMemberOfPredicate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public SqmMemberOfPredicate(
3535
this.pluralPath = pluralPath;
3636
this.leftHandExpression = leftHandExpression;
3737

38-
final SimpleDomainType<?> simpleDomainType = pluralPath.getReferencedPathSource().getElementType();
38+
final SimpleDomainType<?> simpleDomainType = pluralPath.getPluralAttribute().getElementType();
3939

4040
if ( !areTypesComparable( leftHandExpression.getNodeType(), simpleDomainType, nodeBuilder ) ) {
4141
throw new SemanticException(

0 commit comments

Comments
 (0)