HHH-13725 Fix join fetch with alias

This commit is contained in:
Andrea Boriero 2019-11-17 15:50:27 +00:00 committed by Steve Ebersole
parent 93c6c2e7e7
commit 7db245230e
5 changed files with 68 additions and 39 deletions

View File

@ -68,11 +68,8 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor {
DomainResultCreationState creationState) { DomainResultCreationState creationState) {
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
TableReference tableReference = tableGroup.getPrimaryTableReference(); final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
if ( fKeyDirection == ForeignKeyDirection.FROM_PARENT ) { final String identificationVariable = tableReference.getIdentificationVariable();
tableReference = tableGroup.resolveTableReference( keyColumnContainingTable );
}
String identificationVariable = tableReference.getIdentificationVariable();
final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection( final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection(
sqlExpressionResolver.resolveSqlExpression( sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( SqlExpressionResolver.createColumnReferenceKey(
@ -107,60 +104,76 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor {
JoinType joinType, JoinType joinType,
SqlExpressionResolver sqlExpressionResolver, SqlExpressionResolver sqlExpressionResolver,
SqlAstCreationContext creationContext) { SqlAstCreationContext creationContext) {
final TableReference lhsTableReference = getTableReference( lhs, tableGroup, keyColumnContainingTable ); final TableReference keyTableReference = getTableReference( lhs, tableGroup, keyColumnContainingTable );
ColumnReference lhsColumnReference; ColumnReference keyColumnReference;
lhsColumnReference = new ColumnReference( keyColumnReference = new ColumnReference(
lhsTableReference, keyTableReference,
keyColumnExpression, keyColumnExpression,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
); );
final TableReference rhsTableKeyReference = getRhsTableReference( ColumnReference targetColumnReference;
lhs,
tableGroup,
targetColumnContainingTable
);
ColumnReference rhsColumnReference;
if ( targetColumnContainingTable.equals( keyColumnContainingTable ) ) { if ( targetColumnContainingTable.equals( keyColumnContainingTable ) ) {
rhsColumnReference = new ColumnReference( final TableReference targetTableKeyReference = getTableReferenceWhenTargetEqualsKey(
rhsTableKeyReference.getIdentificationVariable(), lhs,
targetColumnExpression, tableGroup,
jdbcMapping, targetColumnContainingTable
creationContext.getSessionFactory()
); );
} targetColumnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
else {
rhsColumnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey( SqlExpressionResolver.createColumnReferenceKey(
rhsTableKeyReference, targetTableKeyReference,
targetColumnExpression targetColumnExpression
), ),
s -> new ColumnReference( s -> new ColumnReference(
rhsTableKeyReference.getIdentificationVariable(), targetTableKeyReference.getIdentificationVariable(),
targetColumnExpression, targetColumnExpression,
jdbcMapping, jdbcMapping,
creationContext.getSessionFactory() creationContext.getSessionFactory()
) )
); );
} }
else {
final TableReference targetTableKeyReference = getTableReference(
lhs,
tableGroup,
targetColumnContainingTable
);
targetColumnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
targetTableKeyReference,
targetColumnExpression
),
s -> new ColumnReference(
targetTableKeyReference.getIdentificationVariable(),
targetColumnExpression,
jdbcMapping,
creationContext.getSessionFactory()
)
);
}
if ( fKeyDirection == ForeignKeyDirection.FROM_PARENT ) {
return new ComparisonPredicate(
targetColumnReference,
ComparisonOperator.EQUAL,
keyColumnReference
);
}
return new ComparisonPredicate( return new ComparisonPredicate(
lhsColumnReference, keyColumnReference,
ComparisonOperator.EQUAL, ComparisonOperator.EQUAL,
rhsColumnReference targetColumnReference
); );
} }
protected TableReference getRhsTableReference(TableGroup lhs, TableGroup tableGroup, String table) { protected TableReference getTableReferenceWhenTargetEqualsKey(TableGroup lhs, TableGroup tableGroup, String table) {
if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) { if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) {
return tableGroup.getPrimaryTableReference(); return tableGroup.getPrimaryTableReference();
} }
if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) { if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) {
return lhs.getPrimaryTableReference(); return lhs.getPrimaryTableReference();
} }
for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) { for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) {
if ( tableJoin.getJoinedTableReference().getTableExpression().equals( table ) ) { if ( tableJoin.getJoinedTableReference().getTableExpression().equals( table ) ) {
return tableJoin.getJoinedTableReference(); return tableJoin.getJoinedTableReference();
@ -177,9 +190,6 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor {
else if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) { else if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) {
return tableGroup.getPrimaryTableReference(); return tableGroup.getPrimaryTableReference();
} }
else if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) {
return tableGroup.getPrimaryTableReference();
}
for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) { for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) {
if ( tableJoin.getJoinedTableReference().getTableExpression().equals( table ) ) { if ( tableJoin.getJoinedTableReference().getTableExpression().equals( table ) ) {
@ -190,7 +200,6 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor {
throw new IllegalStateException( "Could not resolve binding for table `" + table + "`" ); throw new IllegalStateException( "Could not resolve binding for table `" + table + "`" );
} }
@Override @Override
public JavaTypeDescriptor getJavaTypeDescriptor() { public JavaTypeDescriptor getJavaTypeDescriptor() {
return jdbcMapping.getJavaTypeDescriptor(); return jdbcMapping.getJavaTypeDescriptor();

View File

@ -65,7 +65,11 @@ public class FromClauseIndex extends SimpleFromClauseAccessImpl {
if ( fetchesByPath == null ) { if ( fetchesByPath == null ) {
fetchesByPath = new HashMap<>(); fetchesByPath = new HashMap<>();
} }
fetchesByPath.put( sqmJoin.getNavigablePath(), sqmJoin ); NavigablePath navigablePath = sqmJoin.getNavigablePath();
fetchesByPath.put( navigablePath, sqmJoin );
if ( containsAlias( navigablePath ) ) {
fetchesByPath.put( getPathWithoutAlias(navigablePath), sqmJoin );
}
} }
public boolean isResolved(SqmFrom fromElement) { public boolean isResolved(SqmFrom fromElement) {

View File

@ -20,18 +20,26 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
*/ */
public class SimpleFromClauseAccessImpl implements FromClauseAccess { public class SimpleFromClauseAccessImpl implements FromClauseAccess {
protected final Map<NavigablePath, TableGroup> tableGroupMap = new HashMap<>(); protected final Map<NavigablePath, TableGroup> tableGroupMap = new HashMap<>();
private final Map<NavigablePath, TableGroup> tableGroupMapNoAlias = new HashMap<>();
public SimpleFromClauseAccessImpl() { public SimpleFromClauseAccessImpl() {
} }
@Override @Override
public TableGroup findTableGroup(NavigablePath navigablePath) { public TableGroup findTableGroup(NavigablePath navigablePath) {
return tableGroupMap.get( navigablePath ); TableGroup tableGroup = tableGroupMap.get( navigablePath );
if ( tableGroup == null && !containsAlias( navigablePath ) ) {
return tableGroupMapNoAlias.get( navigablePath );
}
return tableGroup;
} }
@Override @Override
public void registerTableGroup(NavigablePath navigablePath, TableGroup tableGroup) { public void registerTableGroup(NavigablePath navigablePath, TableGroup tableGroup) {
final TableGroup previous = tableGroupMap.put( navigablePath, tableGroup ); final TableGroup previous = tableGroupMap.put( navigablePath, tableGroup );
if ( containsAlias( navigablePath ) ) {
tableGroupMapNoAlias.put( getPathWithoutAlias( navigablePath ), tableGroup );
}
if ( previous != null ) { if ( previous != null ) {
SqlTreeCreationLogger.LOGGER.debugf( SqlTreeCreationLogger.LOGGER.debugf(
"Registration of TableGroup [%s] for NavigablePath [%s] overrode previous registration : %s", "Registration of TableGroup [%s] for NavigablePath [%s] overrode previous registration : %s",
@ -42,4 +50,13 @@ public class SimpleFromClauseAccessImpl implements FromClauseAccess {
} }
} }
protected boolean containsAlias(NavigablePath navigablePath) {
return navigablePath.getLocalName().endsWith( ")" );
}
protected NavigablePath getPathWithoutAlias(NavigablePath navigablePath) {
final String fullPath = navigablePath.getFullPath();
final String navigableName = fullPath.substring( fullPath.lastIndexOf( '.' ) + 1, fullPath.lastIndexOf( '(' ) );
return new NavigablePath( navigablePath.getParent(), navigableName );
}
} }

View File

@ -48,7 +48,7 @@ public interface SqlExpressionResolver {
final String qualifier = tableReference.getIdentificationVariable() == null final String qualifier = tableReference.getIdentificationVariable() == null
? tableReference.getTableExpression() ? tableReference.getTableExpression()
: tableReference.getIdentificationVariable(); : tableReference.getIdentificationVariable();
return qualifier + '.' + columnExpression; return qualifier + columnExpression;
} }
/** /**

View File

@ -10,7 +10,6 @@ import javax.persistence.Entity;
import javax.persistence.FetchType; import javax.persistence.FetchType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table; import javax.persistence.Table;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;