Skip to content

Commit 6edba01

Browse files
committed
HHH-17231 Add test for issue
1 parent 2ca37ac commit 6edba01

File tree

2 files changed

+105
-8
lines changed

2 files changed

+105
-8
lines changed

hibernate-core/src/test/java/org/hibernate/orm/test/query/EntityValuedInSubqueryGroupAndOrderTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ public void testInSubqueryGroupBy(SessionFactoryScope scope) {
6565
} );
6666
}
6767

68+
@Test
69+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17231" )
70+
public void testInSubqueryGroupByProp(SessionFactoryScope scope) {
71+
scope.inTransaction( session -> {
72+
final EntityB result = session.createQuery(
73+
"select b from EntityB b " +
74+
"where (b.entityA.name, b.amount) in " +
75+
" (select b2.entityA.name, max(b2.amount) from EntityB b2 " +
76+
" where b2.entityA.unlisted = false " +
77+
" group by b2.entityA)",
78+
EntityB.class
79+
).getSingleResult();
80+
assertThat( result.getAmount() ).isEqualTo( 2 );
81+
} );
82+
}
83+
6884
@Test
6985
public void testTopLevelSelect(SessionFactoryScope scope) {
7086
scope.inTransaction( session -> {

hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaMultiselectGroupByAndOrderByTest.java

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@
1010
import java.util.ArrayList;
1111
import java.util.List;
1212

13+
import org.hibernate.dialect.SybaseASEDialect;
14+
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
15+
import org.hibernate.query.criteria.JpaCriteriaQuery;
16+
import org.hibernate.query.criteria.JpaDerivedRoot;
17+
import org.hibernate.query.criteria.JpaSubQuery;
18+
1319
import org.hibernate.testing.orm.junit.DomainModel;
1420
import org.hibernate.testing.orm.junit.Jira;
1521
import org.hibernate.testing.orm.junit.SessionFactory;
1622
import org.hibernate.testing.orm.junit.SessionFactoryScope;
23+
import org.hibernate.testing.orm.junit.SkipForDialect;
1724
import org.junit.jupiter.api.AfterAll;
1825
import org.junit.jupiter.api.BeforeAll;
1926
import org.junit.jupiter.api.Test;
@@ -26,7 +33,9 @@
2633
import jakarta.persistence.Tuple;
2734
import jakarta.persistence.criteria.CriteriaBuilder;
2835
import jakarta.persistence.criteria.CriteriaQuery;
36+
import jakarta.persistence.criteria.Expression;
2937
import jakarta.persistence.criteria.Join;
38+
import jakarta.persistence.criteria.Path;
3039
import jakarta.persistence.criteria.Root;
3140

3241
import static org.assertj.core.api.Assertions.assertThat;
@@ -39,7 +48,6 @@
3948
CriteriaMultiselectGroupByAndOrderByTest.Secondary.class,
4049
} )
4150
@SessionFactory
42-
@Jira( "https://hibernate.atlassian.net/browse/HHH-17085" )
4351
public class CriteriaMultiselectGroupByAndOrderByTest {
4452
@BeforeAll
4553
public void setUp(SessionFactoryScope scope) {
@@ -72,30 +80,103 @@ public void tearDown(SessionFactoryScope scope) {
7280
}
7381

7482
@Test
83+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17085" )
7584
public void testCriteriaGroupBy(SessionFactoryScope scope) {
76-
executeQuery( scope, false );
85+
executeQuery( scope, false, false );
7786
}
7887

7988
@Test
89+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17085" )
8090
public void testCriteriaGroupByAndOrderBy(SessionFactoryScope scope) {
81-
executeQuery( scope, true );
91+
executeQuery( scope, true, false );
92+
}
93+
94+
@Test
95+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17085" )
96+
public void testCriteriaGroupByAndOrderByAndHaving(SessionFactoryScope scope) {
97+
executeQuery( scope, true, true );
8298
}
8399

84-
private void executeQuery(SessionFactoryScope scope, boolean order) {
100+
private void executeQuery(SessionFactoryScope scope, boolean order, boolean having) {
85101
scope.inTransaction( session -> {
86102
final CriteriaBuilder cb = session.getCriteriaBuilder();
87103
final CriteriaQuery<Tuple> query = cb.createQuery( Tuple.class );
88104
final Root<Primary> root = query.from( Primary.class );
89105
final Join<Primary, Secondary> join = root.join( "secondary" );
106+
final Path<String> entityName = join.get( "entityName" );
107+
final Expression<Number> sum = cb.sum( root.get( "amount" ) );
90108
query.multiselect(
91-
join.get( "entityName" ).alias( "secondary" ),
92-
cb.sum( root.get( "amount" ) ).alias( "sum" )
109+
entityName.alias( "secondary_name" ),
110+
sum.alias( "amount_sum" )
93111
).groupBy( join );
94112
if ( order ) {
95-
query.orderBy( cb.desc( join.get( "entityName" ) ) );
113+
query.orderBy( cb.desc( entityName ) );
114+
}
115+
if ( having ) {
116+
query.having( cb.and(
117+
cb.equal( entityName, "a" ),
118+
cb.gt( sum, 0 )
119+
) );
96120
}
97121
final List<Tuple> resultList = session.createQuery( query ).getResultList();
98-
assertThat( resultList ).hasSize( 3 );
122+
assertThat( resultList ).hasSize( having ? 1 : 3 );
123+
} );
124+
}
125+
126+
@Test
127+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17231" )
128+
public void testSubqueryGroupBy(SessionFactoryScope scope) {
129+
executeSubquery( scope, false, false );
130+
}
131+
132+
@Test
133+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17231" )
134+
@SkipForDialect( dialectClass = SybaseASEDialect.class, reason = "Sybase doesn't support order by + offset in subqueries")
135+
public void testSubqueryGroupByAndOrderBy(SessionFactoryScope scope) {
136+
executeSubquery( scope, true, false );
137+
}
138+
139+
@Test
140+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17231" )
141+
@SkipForDialect( dialectClass = SybaseASEDialect.class, reason = "Sybase doesn't support order by + offset in subqueries")
142+
public void testSubqueryGroupByAndOrderByAndHaving(SessionFactoryScope scope) {
143+
executeSubquery( scope, true, true );
144+
}
145+
146+
private void executeSubquery(SessionFactoryScope scope, boolean order, boolean having) {
147+
scope.inTransaction( session -> {
148+
final HibernateCriteriaBuilder cb = session.getCriteriaBuilder();
149+
final JpaCriteriaQuery<Tuple> query = cb.createTupleQuery();
150+
151+
final JpaSubQuery<Tuple> subquery = query.subquery( Tuple.class );
152+
final Root<Primary> sqRoot = subquery.from( Primary.class );
153+
final Join<Object, Object> secondaryJoin = sqRoot.join( "secondary" );
154+
final Path<String> entityName = secondaryJoin.get( "entityName" );
155+
final Expression<Number> sum = cb.sum( sqRoot.get( "amount" ) );
156+
subquery.multiselect(
157+
entityName.alias( "secondary_name" ),
158+
sum.alias( "amount_sum" )
159+
).groupBy(
160+
secondaryJoin
161+
);
162+
if ( order ) {
163+
subquery.orderBy(
164+
cb.desc( entityName )
165+
).offset( 0 );
166+
}
167+
if ( having ) {
168+
subquery.having( cb.and(
169+
cb.equal( entityName, "a" ),
170+
cb.gt( sum, 0 )
171+
) );
172+
}
173+
final JpaDerivedRoot<Tuple> root = query.from( subquery );
174+
query.multiselect(
175+
root.get( "secondary_name" ),
176+
root.get( "amount_sum" )
177+
);
178+
final List<Tuple> resultList = session.createQuery( query ).getResultList();
179+
assertThat( resultList ).hasSize( having ? 1 : 3 );
99180
} );
100181
}
101182

0 commit comments

Comments
 (0)