Skip to content

Commit 967fed9

Browse files
committed
HHH-19550 Attribute join on correlated from node receives wrong root
1 parent cf645b0 commit 967fed9

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmCorrelation.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@
2020
public interface SqmCorrelation<L,R> extends SqmFrom<L,R>, SqmPathWrapper<R,R> {
2121
SqmRoot<L> getCorrelatedRoot();
2222

23+
@Override
24+
default SqmRoot<?> findRoot() {
25+
return getCorrelatedRoot();
26+
}
2327
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.jpa.criteria.subquery;
6+
7+
import jakarta.persistence.*;
8+
import org.hibernate.Session;
9+
import org.hibernate.query.criteria.*;
10+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
11+
import org.hibernate.testing.orm.junit.Jira;
12+
import org.hibernate.testing.orm.junit.Jpa;
13+
import org.junit.jupiter.api.Test;
14+
15+
import java.io.Serializable;
16+
17+
@Jpa( annotatedClasses = {
18+
AttributeJoinOnCorrelatedOrderedJoinTest.Primary.class,
19+
AttributeJoinOnCorrelatedOrderedJoinTest.Secondary.class,
20+
AttributeJoinOnCorrelatedOrderedJoinTest.Tertiary.class,
21+
} )
22+
@Jira( "https://hibernate.atlassian.net/browse/HHH-19550" )
23+
public class AttributeJoinOnCorrelatedOrderedJoinTest {
24+
25+
@Test
26+
public void test(EntityManagerFactoryScope scope) {
27+
scope.inTransaction( em -> {
28+
final HibernateCriteriaBuilder cb = em.unwrap( Session.class ).getCriteriaBuilder();
29+
final JpaCriteriaQuery<Tuple> query = cb.createTupleQuery();
30+
final JpaRoot<Primary> primary = query.from( Primary.class );
31+
// setup ordered joins
32+
final JpaEntityJoin<Primary, Primary> entityJoinedPrimary = primary.join( Primary.class );
33+
entityJoinedPrimary.on( primary.get( "id" ).equalTo( entityJoinedPrimary.get( "id" ) ) );
34+
// Need an attribute join to correlate
35+
final JpaJoin<?, Secondary> secondaryJoin = primary.join( "secondary" );
36+
37+
final JpaSubQuery<String> subquery = query.subquery( String.class );
38+
final JpaJoin<?, Secondary> correlatedSecondaryJoin = subquery.correlate( secondaryJoin );
39+
// The association join is being added to the result of getLhs().findRoot()
40+
// so if the correlated join returns a wrong node, this is messed up
41+
// and will produce an exception when copying the criteria tree
42+
final JpaJoin<?, Tertiary> tertiary = correlatedSecondaryJoin.join( "tertiary" );
43+
subquery.select( tertiary.get( "name" ) ).where( cb.equal(
44+
tertiary.get( "secondaryFk" ),
45+
correlatedSecondaryJoin.get( "id" )
46+
) );
47+
query.multiselect( primary.get( "id" ), secondaryJoin.get( "name" ), subquery );
48+
em.createQuery( query ).getResultList();
49+
} );
50+
}
51+
52+
@Entity( name = "PrimaryEntity" )
53+
public static class Primary implements Serializable {
54+
@Id
55+
private Integer id;
56+
57+
@ManyToOne(fetch = FetchType.LAZY)
58+
private Secondary secondary;
59+
60+
public Primary() {
61+
}
62+
}
63+
64+
@Entity( name = "SecondaryEntity" )
65+
public static class Secondary implements Serializable {
66+
@Id
67+
private Integer id;
68+
69+
private String name;
70+
@ManyToOne(fetch = FetchType.LAZY)
71+
private Tertiary tertiary;
72+
73+
public Secondary() {
74+
}
75+
76+
public Secondary(Integer id, String name) {
77+
this.id = id;
78+
this.name = name;
79+
}
80+
}
81+
82+
@Entity( name = "TertiaryEntity" )
83+
public static class Tertiary implements Serializable {
84+
@Id
85+
private Integer id;
86+
87+
private Integer secondaryFk;
88+
89+
private String name;
90+
91+
public Tertiary() {
92+
}
93+
94+
public Tertiary(Integer id, Integer secondaryFk, String name) {
95+
this.id = id;
96+
this.secondaryFk = secondaryFk;
97+
this.name = name;
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)