HHH-16721 Make sure join predicate is propagated to correlation on lazy initialization
This commit is contained in:
parent
1cc94c76b9
commit
bbb7bcf389
|
@ -57,7 +57,7 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
|
|||
assert !getTableGroupJoins().contains( join );
|
||||
assert join.getJoinType() == SqlAstJoinType.INNER;
|
||||
querySpec.getFromClause().addRoot( join.getJoinedGroup() );
|
||||
joinPredicateConsumer.accept( join.getPredicate() );
|
||||
registerPredicate( join );
|
||||
super.addTableGroupJoin( join );
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,22 @@ public class CorrelatedTableGroup extends AbstractTableGroup {
|
|||
assert !getTableGroupJoins().contains( join );
|
||||
assert join.getJoinType() == SqlAstJoinType.INNER;
|
||||
querySpec.getFromClause().addRoot( join.getJoinedGroup() );
|
||||
joinPredicateConsumer.accept( join.getPredicate() );
|
||||
registerPredicate( 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
|
||||
public TableReference getTableReference(
|
||||
NavigablePath navigablePath,
|
||||
|
|
|
@ -104,7 +104,16 @@ public class LazyTableGroup extends DelegatingTableGroup {
|
|||
tableGroupConsumer.accept( tableGroup );
|
||||
}
|
||||
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