Skip to content

Commit d852e03

Browse files
committed
HHH-19126 Correct plural attribute path to be collection-typed
1 parent cf6359d commit d852e03

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,12 @@ public Class<E> getBindableJavaType() {
153153
return getElementType().getJavaType();
154154
}
155155

156+
@SuppressWarnings("unchecked")
156157
@Override
157158
public SqmPath<E> createSqmPath(SqmPath<?> lhs, SqmPathSource<?> intermediatePathSource) {
158-
return new SqmPluralValuedSimplePath<>(
159+
// We need an unchecked cast here : PluralPersistentAttribute implements path source with its element type
160+
// but resolving paths from it must produce collection-typed expressions.
161+
return (SqmPath<E>) new SqmPluralValuedSimplePath<>(
159162
PathHelper.append( lhs, this, intermediatePathSource ),
160163
this,
161164
lhs,

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

+22-46
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
@@ -125,12 +124,11 @@ public SqmPath<?> resolveIndexedAccess(
125124
}
126125
SqmFrom<?, ?> path = pathRegistry.findFromByPath( navigablePath.getParent() );
127126
if ( path == null ) {
128-
final PluralPersistentAttribute<?, ?, E> referencedPathSource = getReferencedPathSource();
127+
final SqmPathSource<C> referencedPathSource = getReferencedPathSource();
129128
final SqmFrom<?, Object> parent = pathRegistry.resolveFrom( getLhs() );
130129
final SqmQualifiedJoin<Object, ?> join;
131130
final SqmExpression<?> index;
132131
if ( referencedPathSource instanceof ListPersistentAttribute<?, ?> ) {
133-
//noinspection unchecked
134132
join = new SqmListJoin<>(
135133
parent,
136134
(ListPersistentAttribute<Object, ?>) referencedPathSource,
@@ -142,7 +140,6 @@ public SqmPath<?> resolveIndexedAccess(
142140
index = ( (SqmListJoin<?, ?>) join ).index();
143141
}
144142
else if ( referencedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
145-
//noinspection unchecked
146143
join = new SqmMapJoin<>(
147144
parent,
148145
(MapPersistentAttribute<Object, ?, ?>) referencedPathSource,
@@ -171,38 +168,17 @@ else if ( referencedPathSource instanceof MapPersistentAttribute<?, ?, ?> ) {
171168
}
172169

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

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

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

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public SqmMemberOfPredicate(
3737
this.pluralPath = pluralPath;
3838
this.leftHandExpression = leftHandExpression;
3939

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

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

0 commit comments

Comments
 (0)