Skip to content

Commit 277f10d

Browse files
committed
Support implicit joins in plural path parts and fix issues with type resolving of sub query paths
1 parent 2476898 commit 277f10d

File tree

4 files changed

+26
-35
lines changed

4 files changed

+26
-35
lines changed

hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3871,8 +3871,19 @@ private <X> SqmSubQuery<X> createCollectionReferenceSubQuery(
38713871
);
38723872
final SqmSelectClause selectClause = new SqmSelectClause( false, 1, creationContext.getNodeBuilder() );
38733873
final SqmFromClause fromClause = new SqmFromClause( 1 );
3874-
final SqmCorrelation<?, ?> correlation = ( (AbstractSqmFrom<?, ?>) pluralAttributePath.getLhs() ).createCorrelation();
3875-
final SqmAttributeJoin<?, ?> collectionJoin = correlation.join( pluralAttributePath.getNavigablePath().getUnaliasedLocalName() );
3874+
SqmPath<?> lhs = pluralAttributePath.getLhs();
3875+
final List<String> implicitJoinPaths = new ArrayList<>();
3876+
while ( !( lhs instanceof AbstractSqmFrom<?, ?> ) ) {
3877+
implicitJoinPaths.add( lhs.getNavigablePath().getUnaliasedLocalName() );
3878+
lhs = lhs.getLhs();
3879+
}
3880+
final AbstractSqmFrom<?, ?> correlationBase = (AbstractSqmFrom<?, ?>) lhs;
3881+
final SqmCorrelation<?, ?> correlation = correlationBase.createCorrelation();
3882+
SqmFrom<?, ?> joinBase = correlation;
3883+
for ( int i = implicitJoinPaths.size() - 1; i >= 0; i-- ) {
3884+
joinBase = joinBase.join( implicitJoinPaths.get( i ) );
3885+
}
3886+
final SqmAttributeJoin<?, ?> collectionJoin = joinBase.join( pluralAttributePath.getNavigablePath().getUnaliasedLocalName() );
38763887
fromClause.addRoot( correlation.getCorrelatedRoot() );
38773888
if ( collectionReferenceCtx == null ) {
38783889
final SqmLiteral<Integer> literal = new SqmLiteral<>(

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmMappingModelHelper.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ private static ModelPart resolveSqmPath(
185185
return domainModel.findEntityDescriptor( entityDomainType.getHibernateEntityName() );
186186
}
187187
final TableGroup lhsTableGroup = tableGroupLocator.apply( sqmPath.getLhs().getNavigablePath() );
188-
return lhsTableGroup.getModelPart().findSubPart( sqmPath.getReferencedPathSource().getPathName(), null );
188+
final ModelPartContainer modelPart;
189+
if ( lhsTableGroup == null ) {
190+
modelPart = (ModelPartContainer) resolveSqmPath( sqmPath.getLhs(), domainModel, tableGroupLocator );
191+
}
192+
else {
193+
modelPart = lhsTableGroup.getModelPart();
194+
}
195+
return modelPart.findSubPart( sqmPath.getReferencedPathSource().getPathName(), null );
189196
}
190197

191198
public static EntityMappingType resolveExplicitTreatTarget(

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4555,7 +4555,6 @@ private MappingModelExpressible<?> determineValueMapping(SqmExpression<?> sqmExp
45554555
}
45564556
else if ( sqmExpression instanceof SqmPath ) {
45574557
log.debugf( "Determining mapping-model type for SqmPath : %s ", sqmExpression );
4558-
prepareReusablePath( (SqmPath<?>) sqmExpression, fromClauseIndex, () -> null );
45594558
final MappingMetamodel domainModel = creationContext.getSessionFactory()
45604559
.getRuntimeMetamodels()
45614560
.getMappingMetamodel();
@@ -4577,40 +4576,16 @@ else if ( sqmExpression instanceof SqmSubQuery<?> ) {
45774576
final SqmSelectClause selectClause = subQuery.getQuerySpec().getSelectClause();
45784577
if ( selectClause.getSelections().size() == 1 ) {
45794578
final SqmSelection<?> subQuerySelection = selectClause.getSelections().get( 0 );
4579+
final SqmSelectableNode<?> selectableNode = subQuerySelection.getSelectableNode();
4580+
if ( selectableNode instanceof SqmExpression<?> ) {
4581+
return determineValueMapping( (SqmExpression<?>) selectableNode, fromClauseIndex );
4582+
}
45804583
final SqmExpressible<?> selectionNodeType = subQuerySelection.getNodeType();
45814584
if ( selectionNodeType != null ) {
4582-
final SqmExpressible<?> sqmExpressible;
4583-
if ( selectionNodeType instanceof PluralPersistentAttribute ) {
4584-
sqmExpressible = ( (PluralPersistentAttribute<?,?,?>) selectionNodeType ).getElementPathSource();
4585-
}
4586-
else if ( selectionNodeType instanceof SqmPathSource<?>) {
4587-
final SqmPathSource<?> pathSource = (SqmPathSource<?>) selectionNodeType;
4588-
final CollectionPart.Nature partNature = CollectionPart.Nature.fromName(
4589-
pathSource.getPathName()
4590-
);
4591-
if ( partNature == null ) {
4592-
sqmExpressible = selectionNodeType;
4593-
}
4594-
else {
4595-
final SqmPath<?> sqmPath = (SqmPath<?>) subQuerySelection.getSelectableNode();
4596-
final NavigablePath navigablePath = sqmPath.getNavigablePath().getParent();
4597-
if ( navigablePath.getParent() != null ) {
4598-
final TableGroup parentTableGroup = fromClauseIndex.findTableGroup( navigablePath.getParent() );
4599-
final PluralAttributeMapping pluralPart = (PluralAttributeMapping) parentTableGroup.getModelPart()
4600-
.findSubPart( navigablePath.getUnaliasedLocalName(), null );
4601-
return pluralPart.findSubPart( pathSource.getPathName(), null );
4602-
}
4603-
return fromClauseIndex.findTableGroup( navigablePath ).getModelPart();
4604-
}
4605-
}
4606-
else {
4607-
sqmExpressible = selectionNodeType;
4608-
}
4609-
46104585
final MappingMetamodel domainModel = creationContext.getSessionFactory()
46114586
.getRuntimeMetamodels()
46124587
.getMappingMetamodel();
4613-
final MappingModelExpressible<?> expressible = domainModel.resolveMappingExpressible(sqmExpressible, this::findTableGroupByPath );
4588+
final MappingModelExpressible<?> expressible = domainModel.resolveMappingExpressible(selectionNodeType, this::findTableGroupByPath );
46144589

46154590
if ( expressible != null ) {
46164591
return expressible;

hibernate-core/src/test/java/org/hibernate/orm/test/mapping/collections/mapcompelem/MapCompositeElementTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import java.util.List;
1010

1111
import org.hibernate.testing.orm.junit.DomainModel;
12-
import org.hibernate.testing.orm.junit.NotImplementedYet;
1312
import org.hibernate.testing.orm.junit.SessionFactory;
1413
import org.hibernate.testing.orm.junit.SessionFactoryScope;
1514
import org.junit.jupiter.api.Test;
@@ -61,7 +60,6 @@ public void testMapCompositeElementWithFormula(SessionFactoryScope scope) {
6160

6261
@SuppressWarnings( {"unchecked"})
6362
@Test
64-
@NotImplementedYet( strict = false )
6563
public void testQueryMapCompositeElement(SessionFactoryScope scope) {
6664
scope.inTransaction( (s) -> {
6765
Part top = new Part("top", "The top part");

0 commit comments

Comments
 (0)