Support implicit joins in plural path parts and fix issues with type resolving of sub query paths
This commit is contained in:
parent
247689824f
commit
277f10d987
|
@ -3871,8 +3871,19 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
);
|
);
|
||||||
final SqmSelectClause selectClause = new SqmSelectClause( false, 1, creationContext.getNodeBuilder() );
|
final SqmSelectClause selectClause = new SqmSelectClause( false, 1, creationContext.getNodeBuilder() );
|
||||||
final SqmFromClause fromClause = new SqmFromClause( 1 );
|
final SqmFromClause fromClause = new SqmFromClause( 1 );
|
||||||
final SqmCorrelation<?, ?> correlation = ( (AbstractSqmFrom<?, ?>) pluralAttributePath.getLhs() ).createCorrelation();
|
SqmPath<?> lhs = pluralAttributePath.getLhs();
|
||||||
final SqmAttributeJoin<?, ?> collectionJoin = correlation.join( pluralAttributePath.getNavigablePath().getUnaliasedLocalName() );
|
final List<String> implicitJoinPaths = new ArrayList<>();
|
||||||
|
while ( !( lhs instanceof AbstractSqmFrom<?, ?> ) ) {
|
||||||
|
implicitJoinPaths.add( lhs.getNavigablePath().getUnaliasedLocalName() );
|
||||||
|
lhs = lhs.getLhs();
|
||||||
|
}
|
||||||
|
final AbstractSqmFrom<?, ?> correlationBase = (AbstractSqmFrom<?, ?>) lhs;
|
||||||
|
final SqmCorrelation<?, ?> correlation = correlationBase.createCorrelation();
|
||||||
|
SqmFrom<?, ?> joinBase = correlation;
|
||||||
|
for ( int i = implicitJoinPaths.size() - 1; i >= 0; i-- ) {
|
||||||
|
joinBase = joinBase.join( implicitJoinPaths.get( i ) );
|
||||||
|
}
|
||||||
|
final SqmAttributeJoin<?, ?> collectionJoin = joinBase.join( pluralAttributePath.getNavigablePath().getUnaliasedLocalName() );
|
||||||
fromClause.addRoot( correlation.getCorrelatedRoot() );
|
fromClause.addRoot( correlation.getCorrelatedRoot() );
|
||||||
if ( collectionReferenceCtx == null ) {
|
if ( collectionReferenceCtx == null ) {
|
||||||
final SqmLiteral<Integer> literal = new SqmLiteral<>(
|
final SqmLiteral<Integer> literal = new SqmLiteral<>(
|
||||||
|
|
|
@ -185,7 +185,14 @@ public class SqmMappingModelHelper {
|
||||||
return domainModel.findEntityDescriptor( entityDomainType.getHibernateEntityName() );
|
return domainModel.findEntityDescriptor( entityDomainType.getHibernateEntityName() );
|
||||||
}
|
}
|
||||||
final TableGroup lhsTableGroup = tableGroupLocator.apply( sqmPath.getLhs().getNavigablePath() );
|
final TableGroup lhsTableGroup = tableGroupLocator.apply( sqmPath.getLhs().getNavigablePath() );
|
||||||
return lhsTableGroup.getModelPart().findSubPart( sqmPath.getReferencedPathSource().getPathName(), null );
|
final ModelPartContainer modelPart;
|
||||||
|
if ( lhsTableGroup == null ) {
|
||||||
|
modelPart = (ModelPartContainer) resolveSqmPath( sqmPath.getLhs(), domainModel, tableGroupLocator );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
modelPart = lhsTableGroup.getModelPart();
|
||||||
|
}
|
||||||
|
return modelPart.findSubPart( sqmPath.getReferencedPathSource().getPathName(), null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityMappingType resolveExplicitTreatTarget(
|
public static EntityMappingType resolveExplicitTreatTarget(
|
||||||
|
|
|
@ -4555,7 +4555,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
else if ( sqmExpression instanceof SqmPath ) {
|
else if ( sqmExpression instanceof SqmPath ) {
|
||||||
log.debugf( "Determining mapping-model type for SqmPath : %s ", sqmExpression );
|
log.debugf( "Determining mapping-model type for SqmPath : %s ", sqmExpression );
|
||||||
prepareReusablePath( (SqmPath<?>) sqmExpression, fromClauseIndex, () -> null );
|
|
||||||
final MappingMetamodel domainModel = creationContext.getSessionFactory()
|
final MappingMetamodel domainModel = creationContext.getSessionFactory()
|
||||||
.getRuntimeMetamodels()
|
.getRuntimeMetamodels()
|
||||||
.getMappingMetamodel();
|
.getMappingMetamodel();
|
||||||
|
@ -4577,40 +4576,16 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
final SqmSelectClause selectClause = subQuery.getQuerySpec().getSelectClause();
|
final SqmSelectClause selectClause = subQuery.getQuerySpec().getSelectClause();
|
||||||
if ( selectClause.getSelections().size() == 1 ) {
|
if ( selectClause.getSelections().size() == 1 ) {
|
||||||
final SqmSelection<?> subQuerySelection = selectClause.getSelections().get( 0 );
|
final SqmSelection<?> subQuerySelection = selectClause.getSelections().get( 0 );
|
||||||
|
final SqmSelectableNode<?> selectableNode = subQuerySelection.getSelectableNode();
|
||||||
|
if ( selectableNode instanceof SqmExpression<?> ) {
|
||||||
|
return determineValueMapping( (SqmExpression<?>) selectableNode, fromClauseIndex );
|
||||||
|
}
|
||||||
final SqmExpressible<?> selectionNodeType = subQuerySelection.getNodeType();
|
final SqmExpressible<?> selectionNodeType = subQuerySelection.getNodeType();
|
||||||
if ( selectionNodeType != null ) {
|
if ( selectionNodeType != null ) {
|
||||||
final SqmExpressible<?> sqmExpressible;
|
|
||||||
if ( selectionNodeType instanceof PluralPersistentAttribute ) {
|
|
||||||
sqmExpressible = ( (PluralPersistentAttribute<?,?,?>) selectionNodeType ).getElementPathSource();
|
|
||||||
}
|
|
||||||
else if ( selectionNodeType instanceof SqmPathSource<?>) {
|
|
||||||
final SqmPathSource<?> pathSource = (SqmPathSource<?>) selectionNodeType;
|
|
||||||
final CollectionPart.Nature partNature = CollectionPart.Nature.fromName(
|
|
||||||
pathSource.getPathName()
|
|
||||||
);
|
|
||||||
if ( partNature == null ) {
|
|
||||||
sqmExpressible = selectionNodeType;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final SqmPath<?> sqmPath = (SqmPath<?>) subQuerySelection.getSelectableNode();
|
|
||||||
final NavigablePath navigablePath = sqmPath.getNavigablePath().getParent();
|
|
||||||
if ( navigablePath.getParent() != null ) {
|
|
||||||
final TableGroup parentTableGroup = fromClauseIndex.findTableGroup( navigablePath.getParent() );
|
|
||||||
final PluralAttributeMapping pluralPart = (PluralAttributeMapping) parentTableGroup.getModelPart()
|
|
||||||
.findSubPart( navigablePath.getUnaliasedLocalName(), null );
|
|
||||||
return pluralPart.findSubPart( pathSource.getPathName(), null );
|
|
||||||
}
|
|
||||||
return fromClauseIndex.findTableGroup( navigablePath ).getModelPart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sqmExpressible = selectionNodeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
final MappingMetamodel domainModel = creationContext.getSessionFactory()
|
final MappingMetamodel domainModel = creationContext.getSessionFactory()
|
||||||
.getRuntimeMetamodels()
|
.getRuntimeMetamodels()
|
||||||
.getMappingMetamodel();
|
.getMappingMetamodel();
|
||||||
final MappingModelExpressible<?> expressible = domainModel.resolveMappingExpressible(sqmExpressible, this::findTableGroupByPath );
|
final MappingModelExpressible<?> expressible = domainModel.resolveMappingExpressible(selectionNodeType, this::findTableGroupByPath );
|
||||||
|
|
||||||
if ( expressible != null ) {
|
if ( expressible != null ) {
|
||||||
return expressible;
|
return expressible;
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.orm.test.mapping.collections.mapcompelem;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.hibernate.testing.orm.junit.NotImplementedYet;
|
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -61,7 +60,6 @@ public class MapCompositeElementTest {
|
||||||
|
|
||||||
@SuppressWarnings( {"unchecked"})
|
@SuppressWarnings( {"unchecked"})
|
||||||
@Test
|
@Test
|
||||||
@NotImplementedYet( strict = false )
|
|
||||||
public void testQueryMapCompositeElement(SessionFactoryScope scope) {
|
public void testQueryMapCompositeElement(SessionFactoryScope scope) {
|
||||||
scope.inTransaction( (s) -> {
|
scope.inTransaction( (s) -> {
|
||||||
Part top = new Part("top", "The top part");
|
Part top = new Part("top", "The top part");
|
||||||
|
|
Loading…
Reference in New Issue