HHH-16721 Make sure join predicate is propagated to correlation on lazy initialization
This commit is contained in:
parent
380962bd37
commit
01c8295968
|
@ -57,7 +57,7 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
|
||||||
assert !getTableGroupJoins().contains( join );
|
assert !getTableGroupJoins().contains( join );
|
||||||
assert join.getJoinType() == SqlAstJoinType.INNER;
|
assert join.getJoinType() == SqlAstJoinType.INNER;
|
||||||
querySpec.getFromClause().addRoot( join.getJoinedGroup() );
|
querySpec.getFromClause().addRoot( join.getJoinedGroup() );
|
||||||
joinPredicateConsumer.accept( join.getPredicate() );
|
registerPredicate( join );
|
||||||
super.addTableGroupJoin( join );
|
super.addTableGroupJoin( join );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,10 +71,22 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
|
||||||
assert !getTableGroupJoins().contains( join );
|
assert !getTableGroupJoins().contains( join );
|
||||||
assert join.getJoinType() == SqlAstJoinType.INNER;
|
assert join.getJoinType() == SqlAstJoinType.INNER;
|
||||||
querySpec.getFromClause().addRoot( join.getJoinedGroup() );
|
querySpec.getFromClause().addRoot( join.getJoinedGroup() );
|
||||||
joinPredicateConsumer.accept( join.getPredicate() );
|
registerPredicate( join );
|
||||||
super.addNestedTableGroupJoin( join );
|
super.addNestedTableGroupJoin( join );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerPredicate(TableGroupJoin join) {
|
||||||
|
if ( join.getPredicate() != null ) {
|
||||||
|
joinPredicateConsumer.accept( join.getPredicate() );
|
||||||
|
}
|
||||||
|
else if ( join.getJoinedGroup() instanceof LazyTableGroup ) {
|
||||||
|
// Wait for the table group to get initialized before consuming the predicate
|
||||||
|
( (LazyTableGroup) join.getJoinedGroup() ).setTableGroupInitializerCallback(
|
||||||
|
tableGroup -> joinPredicateConsumer.accept( join.getPredicate() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableReference getTableReference(
|
public TableReference getTableReference(
|
||||||
NavigablePath navigablePath,
|
NavigablePath navigablePath,
|
||||||
|
|
|
@ -104,7 +104,16 @@ public class LazyTableGroup extends DelegatingTableGroup {
|
||||||
tableGroupConsumer.accept( tableGroup );
|
tableGroupConsumer.accept( tableGroup );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.tableGroupConsumer = tableGroupConsumer;
|
final Consumer<TableGroup> previousConsumer = this.tableGroupConsumer;
|
||||||
|
if (previousConsumer != null ) {
|
||||||
|
this.tableGroupConsumer = tg -> {
|
||||||
|
previousConsumer.accept( tg );
|
||||||
|
tableGroupConsumer.accept( tg );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tableGroupConsumer = tableGroupConsumer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package org.hibernate.orm.test.query;
|
||||||
|
|
||||||
|
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.JiraKey;
|
||||||
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@JiraKey("HHH-16721")
|
||||||
|
@DomainModel(annotatedClasses = {
|
||||||
|
ImplicitJoinInSubqueryTest.A.class,
|
||||||
|
ImplicitJoinInSubqueryTest.B.class,
|
||||||
|
ImplicitJoinInSubqueryTest.C.class
|
||||||
|
})
|
||||||
|
@SessionFactory(useCollectingStatementInspector = true)
|
||||||
|
public class ImplicitJoinInSubqueryTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testImplicitJoinInSubquery(SessionFactoryScope scope) {
|
||||||
|
SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||||
|
statementInspector.clear();
|
||||||
|
scope.inTransaction(
|
||||||
|
entityManager -> {
|
||||||
|
entityManager.createSelectionQuery(
|
||||||
|
"select 1 from A a where exists (select 1 from B b where a.b.c.id = 5)"
|
||||||
|
).getResultList();
|
||||||
|
assertThat( statementInspector.getSqlQueries().get( 0 ) ).contains( "b2_0.id=a1_0.b_id" );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "A")
|
||||||
|
public static class A {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
Long id;
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
B b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "B")
|
||||||
|
public static class B {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
Long id;
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
C c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "C")
|
||||||
|
public static class C {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
Long id;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue