Skip to content

Commit 05c55c2

Browse files
committed
HHH-19126 Correct plural attribute path to be collection-typed
1 parent 06a2b9e commit 05c55c2

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
@@ -143,6 +143,7 @@ public Class<E> getBindableJavaType() {
143143
return getElementType().getJavaType();
144144
}
145145

146+
@SuppressWarnings("unchecked")
146147
@Override
147148
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
148149
final NavigablePath navigablePath;
@@ -152,7 +153,9 @@ public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePat
152153
else {
153154
navigablePath = lhs.getNavigablePath().append( intermediatePathSource.getPathName() ).append( getPathName() );
154155
}
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
navigablePath,
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
@@ -18,50 +18,55 @@
1818
import org.hibernate.query.hql.spi.SqmPathRegistry;
1919
import org.hibernate.query.sqm.NodeBuilder;
2020
import org.hibernate.query.sqm.SemanticQueryWalker;
21+
import org.hibernate.query.sqm.SqmPathSource;
2122
import org.hibernate.query.sqm.tree.SqmCopyContext;
2223
import org.hibernate.query.sqm.tree.SqmJoinType;
2324
import org.hibernate.query.sqm.tree.expression.SqmExpression;
2425
import org.hibernate.query.sqm.tree.from.SqmFrom;
26+
import org.hibernate.type.descriptor.java.JavaType;
2527
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
2628

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

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

5257
@Override
53-
public SqmPluralValuedSimplePath<E> copy(SqmCopyContext context) {
54-
final SqmPluralValuedSimplePath<E> existing = context.getCopy( this );
58+
public SqmPluralValuedSimplePath<C> copy(SqmCopyContext context) {
59+
final SqmPluralValuedSimplePath<C> existing = context.getCopy( this );
5560
if ( existing != null ) {
5661
return existing;
5762
}
5863

5964
final SqmPath<?> lhsCopy = getLhs().copy( context );
60-
final SqmPluralValuedSimplePath<E> path = context.registerCopy(
65+
final SqmPluralValuedSimplePath<C> path = context.registerCopy(
6166
this,
6267
new SqmPluralValuedSimplePath<>(
6368
getNavigablePathCopy( lhsCopy ),
64-
getModel(),
69+
(PluralPersistentAttribute<?,C,?>) getModel(),
6570
lhsCopy,
6671
getExplicitAlias(),
6772
nodeBuilder()
@@ -71,19 +76,13 @@ public SqmPluralValuedSimplePath<E> copy(SqmCopyContext context) {
7176
return path;
7277
}
7378

74-
@Override
75-
public PluralPersistentAttribute<?, ?, E> getReferencedPathSource() {
76-
return (PluralPersistentAttribute<?, ?, E>) super.getReferencedPathSource();
77-
}
78-
79-
@Override
80-
public PluralPersistentAttribute<?, ?, E> getModel() {
81-
return (PluralPersistentAttribute<?, ?, E>) super.getModel();
79+
public PluralPersistentAttribute<?, C, ?> getPluralAttribute() {
80+
return (PluralPersistentAttribute<?, C, ?>) getModel();
8281
}
8382

8483
@Override
85-
public PluralPersistentAttribute<?,?,E> getNodeType() {
86-
return getReferencedPathSource();
84+
public JavaType<C> getJavaTypeDescriptor() {
85+
return getPluralAttribute().getAttributeJavaType();
8786
}
8887

8988
@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 SqmQualifiedJoin<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,
@@ -168,33 +165,12 @@ else if ( referencedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
168165
}
169166

170167
@Override
171-
public <S extends E> SqmTreatedSimplePath<E,S> treatAs(Class<S> treatJavaType) throws PathException {
172-
return (SqmTreatedSimplePath<E, S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
168+
public <S extends C> SqmTreatedSimplePath<C,S> treatAs(Class<S> treatJavaType) throws PathException {
169+
return (SqmTreatedSimplePath<C, S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
173170
}
174171

175172
@Override
176-
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
173+
public <S extends C> SqmTreatedPath<C, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
177174
return getTreatedPath( treatTarget );
178175
}
179-
180-
// @Override
181-
// public DomainResult createDomainResult(
182-
// String resultVariable,
183-
// DomainResultCreationState creationState,
184-
// DomainResultCreationContext creationContext) {
185-
// return new CollectionResultImpl(
186-
// getReferencedNavigable().getPluralAttribute().getDescribedAttribute(),
187-
// getNavigablePath(),
188-
// resultVariable,
189-
// LockMode.NONE,
190-
// getReferencedNavigable().getPluralAttribute().getCollectionKeyDescriptor().createDomainResult(
191-
// getNavigablePath().append( "{id}" ),
192-
// null,
193-
// creationState,
194-
// creationContext
195-
// ),
196-
// initializerProducerCreator.createProducer( resultVariable, creationState, creationContext )
197-
// );
198-
// }
199-
200176
}

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.leftHandExpression = leftHandExpression;
3636

3737
leftHandExpression.applyInferableType(
38-
( (SqmPluralValuedSimplePath<?>) pluralPath ).getReferencedPathSource().getElementType()
38+
( (SqmPluralValuedSimplePath<?>) pluralPath ).getPluralAttribute().getElementType()
3939
);
4040
}
4141

0 commit comments

Comments
 (0)