diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index ffeba0d97c..3520c7c626 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -3618,12 +3618,7 @@ public abstract class AbstractSqlAstTranslator implemen clauseStack.push( Clause.FROM ); String separator = NO_SEPARATOR; for ( TableGroup root : fromClause.getRoots() ) { - // Skip virtual table group roots which we use for simple correlations - if ( !( root instanceof VirtualTableGroup ) ) { - appendSql( separator ); - renderRootTableGroup( root, null ); - separator = COMA_SEPARATOR; - } + separator = renderFromClauseRoot( root, separator ); } } finally { @@ -3632,6 +3627,23 @@ public abstract class AbstractSqlAstTranslator implemen } } + private String renderFromClauseRoot(TableGroup root, String separator) { + if ( root instanceof VirtualTableGroup ) { + for ( TableGroupJoin tableGroupJoin : root.getTableGroupJoins() ) { + separator = renderFromClauseRoot( tableGroupJoin.getJoinedGroup(), separator ); + } + for ( TableGroupJoin tableGroupJoin : root.getNestedTableGroupJoins() ) { + separator = renderFromClauseRoot( tableGroupJoin.getJoinedGroup(), separator ); + } + } + else { + appendSql( separator ); + renderRootTableGroup( root, null ); + separator = COMA_SEPARATOR; + } + return separator; + } + protected void renderRootTableGroup(TableGroup tableGroup, List tableGroupJoinCollector) { final LockMode effectiveLockMode = getEffectiveLockMode( tableGroup.getSourceAlias() ); final boolean usesLockHint = renderPrimaryTableReference( tableGroup, effectiveLockMode ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java index 5ce92426c8..f437ee8bb9 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/CorrelatedTableGroup.java @@ -119,4 +119,7 @@ public class CorrelatedTableGroup extends AbstractTableGroup { return Collections.emptyList(); } + public Consumer getJoinPredicateConsumer() { + return joinPredicateConsumer; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardVirtualTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardVirtualTableGroup.java index b8df566a9e..3b33527805 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardVirtualTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/StandardVirtualTableGroup.java @@ -71,6 +71,34 @@ public class StandardVirtualTableGroup extends AbstractTableGroup implements Vir return underlyingTableGroup.getTableReferenceJoins(); } + @Override + public void addTableGroupJoin(TableGroupJoin join) { + super.addTableGroupJoin( join ); + registerPredicateOnCorrelatedTableGroup( join ); + } + + @Override + public void prependTableGroupJoin(NavigablePath navigablePath, TableGroupJoin join) { + super.prependTableGroupJoin( navigablePath, join ); + registerPredicateOnCorrelatedTableGroup( join ); + } + + @Override + public void addNestedTableGroupJoin(TableGroupJoin join) { + super.addNestedTableGroupJoin( join ); + registerPredicateOnCorrelatedTableGroup( join ); + } + + private void registerPredicateOnCorrelatedTableGroup(TableGroupJoin join) { + TableGroup tableGroup = underlyingTableGroup; + while ( tableGroup instanceof StandardVirtualTableGroup ) { + tableGroup = ( (StandardVirtualTableGroup) tableGroup ).underlyingTableGroup; + } + if ( tableGroup instanceof CorrelatedTableGroup ) { + ( (CorrelatedTableGroup) tableGroup ).getJoinPredicateConsumer().accept( join.getPredicate() ); + } + } + @Override public TableReference getTableReferenceInternal( NavigablePath navigablePath,