diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java index d49b3963a8..5e0db3f58d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/SimpleForeignKeyDescriptor.java @@ -68,11 +68,8 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor { DomainResultCreationState creationState) { final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState(); final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver(); - TableReference tableReference = tableGroup.getPrimaryTableReference(); - if ( fKeyDirection == ForeignKeyDirection.FROM_PARENT ) { - tableReference = tableGroup.resolveTableReference( keyColumnContainingTable ); - } - String identificationVariable = tableReference.getIdentificationVariable(); + final TableReference tableReference = tableGroup.resolveTableReference( keyColumnContainingTable ); + final String identificationVariable = tableReference.getIdentificationVariable(); final SqlSelection sqlSelection = sqlExpressionResolver.resolveSqlSelection( sqlExpressionResolver.resolveSqlExpression( SqlExpressionResolver.createColumnReferenceKey( @@ -107,60 +104,76 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor { JoinType joinType, SqlExpressionResolver sqlExpressionResolver, SqlAstCreationContext creationContext) { - final TableReference lhsTableReference = getTableReference( lhs, tableGroup, keyColumnContainingTable ); - ColumnReference lhsColumnReference; - lhsColumnReference = new ColumnReference( - lhsTableReference, + final TableReference keyTableReference = getTableReference( lhs, tableGroup, keyColumnContainingTable ); + ColumnReference keyColumnReference; + keyColumnReference = new ColumnReference( + keyTableReference, keyColumnExpression, jdbcMapping, creationContext.getSessionFactory() ); - final TableReference rhsTableKeyReference = getRhsTableReference( - lhs, - tableGroup, - targetColumnContainingTable - ); - - ColumnReference rhsColumnReference; + ColumnReference targetColumnReference; if ( targetColumnContainingTable.equals( keyColumnContainingTable ) ) { - rhsColumnReference = new ColumnReference( - rhsTableKeyReference.getIdentificationVariable(), - targetColumnExpression, - jdbcMapping, - creationContext.getSessionFactory() + final TableReference targetTableKeyReference = getTableReferenceWhenTargetEqualsKey( + lhs, + tableGroup, + targetColumnContainingTable ); - } - else { - - rhsColumnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression( + targetColumnReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression( SqlExpressionResolver.createColumnReferenceKey( - rhsTableKeyReference, + targetTableKeyReference, targetColumnExpression ), s -> new ColumnReference( - rhsTableKeyReference.getIdentificationVariable(), + targetTableKeyReference.getIdentificationVariable(), targetColumnExpression, jdbcMapping, 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( - lhsColumnReference, + keyColumnReference, 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 ) ) { return tableGroup.getPrimaryTableReference(); } if ( lhs.getPrimaryTableReference().getTableExpression().equals( table ) ) { return lhs.getPrimaryTableReference(); } + for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) { if ( tableJoin.getJoinedTableReference().getTableExpression().equals( table ) ) { return tableJoin.getJoinedTableReference(); @@ -177,9 +190,6 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor { else if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) { return tableGroup.getPrimaryTableReference(); } - else if ( tableGroup.getPrimaryTableReference().getTableExpression().equals( table ) ) { - return tableGroup.getPrimaryTableReference(); - } for ( TableReferenceJoin tableJoin : lhs.getTableReferenceJoins() ) { 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 + "`" ); } - @Override public JavaTypeDescriptor getJavaTypeDescriptor() { return jdbcMapping.getJavaTypeDescriptor(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/FromClauseIndex.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/FromClauseIndex.java index 6f47249467..bf929b0dc2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/FromClauseIndex.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/FromClauseIndex.java @@ -65,7 +65,11 @@ public class FromClauseIndex extends SimpleFromClauseAccessImpl { if ( fetchesByPath == null ) { 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) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SimpleFromClauseAccessImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SimpleFromClauseAccessImpl.java index efe31f4dd7..7d02a57a28 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SimpleFromClauseAccessImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SimpleFromClauseAccessImpl.java @@ -20,18 +20,26 @@ import org.hibernate.sql.ast.tree.from.TableGroup; */ public class SimpleFromClauseAccessImpl implements FromClauseAccess { protected final Map tableGroupMap = new HashMap<>(); + private final Map tableGroupMapNoAlias = new HashMap<>(); public SimpleFromClauseAccessImpl() { } @Override 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 public void registerTableGroup(NavigablePath navigablePath, TableGroup tableGroup) { final TableGroup previous = tableGroupMap.put( navigablePath, tableGroup ); + if ( containsAlias( navigablePath ) ) { + tableGroupMapNoAlias.put( getPathWithoutAlias( navigablePath ), tableGroup ); + } if ( previous != null ) { SqlTreeCreationLogger.LOGGER.debugf( "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 ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java index f3d692ebcb..526a2c3e8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/SqlExpressionResolver.java @@ -48,7 +48,7 @@ public interface SqlExpressionResolver { final String qualifier = tableReference.getIdentificationVariable() == null ? tableReference.getTableExpression() : tableReference.getIdentificationVariable(); - return qualifier + '.' + columnExpression; + return qualifier + columnExpression; } /** diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/exec/manytoone/ManyToOneTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/exec/manytoone/ManyToOneTest.java index 7b762d00ce..eb791a65b0 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/exec/manytoone/ManyToOneTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/exec/manytoone/ManyToOneTest.java @@ -10,7 +10,6 @@ import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.ManyToOne; -import javax.persistence.OneToOne; import javax.persistence.Table; import org.hibernate.Hibernate;