Skip to content

Commit 8914f5b

Browse files
committed
HHH-17104 Add test for issue
1 parent 4158c7a commit 8914f5b

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
6+
*/
7+
package org.hibernate.orm.test.query.hql;
8+
9+
import java.util.List;
10+
11+
import org.hibernate.QueryException;
12+
13+
import org.hibernate.testing.orm.junit.DomainModel;
14+
import org.hibernate.testing.orm.junit.Jira;
15+
import org.hibernate.testing.orm.junit.SessionFactory;
16+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
17+
import org.junit.jupiter.api.AfterAll;
18+
import org.junit.jupiter.api.BeforeAll;
19+
import org.junit.jupiter.api.Test;
20+
21+
import jakarta.persistence.Entity;
22+
import jakarta.persistence.FetchType;
23+
import jakarta.persistence.GeneratedValue;
24+
import jakarta.persistence.Id;
25+
import jakarta.persistence.JoinColumn;
26+
import jakarta.persistence.ManyToOne;
27+
import jakarta.persistence.OneToMany;
28+
import jakarta.persistence.Tuple;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
import static org.assertj.core.api.Assertions.fail;
32+
33+
/**
34+
* @author Marco Belladelli
35+
*/
36+
@DomainModel( annotatedClasses = {
37+
JoinedCollectionMaxIdTest.TestEntity.class,
38+
JoinedCollectionMaxIdTest.ListItem.class
39+
} )
40+
@SessionFactory
41+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17104" )
42+
public class JoinedCollectionMaxIdTest {
43+
@BeforeAll
44+
public void setUp(SessionFactoryScope scope) {
45+
scope.inTransaction( session -> {
46+
final TestEntity entity = new TestEntity();
47+
session.persist( entity );
48+
session.persist( new ListItem( 1L, "item_1", entity ) );
49+
session.persist( new ListItem( 2L, "item_2", entity ) );
50+
} );
51+
}
52+
53+
@AfterAll
54+
public void tearDown(SessionFactoryScope scope) {
55+
scope.inTransaction( session -> {
56+
session.createMutationQuery( "delete from ListItem" ).executeUpdate();
57+
session.createMutationQuery( "delete from TestEntity" ).executeUpdate();
58+
} );
59+
}
60+
61+
@Test
62+
public void testInvalidDynamicInstantiation(SessionFactoryScope scope) {
63+
scope.inTransaction( session -> {
64+
try {
65+
session.createQuery( String.format(
66+
"select new %s(e, max(li)) from TestEntity e join e.listItems li group by e.id",
67+
DataProjection.class.getName()
68+
), Tuple.class ).getResultList();
69+
fail( "Calling a function with an entity-typed parameter should not be allowed" );
70+
}
71+
catch (Exception e) {
72+
assertThat( e.getCause() ).isInstanceOf( QueryException.class );
73+
assertThat( e.getMessage() ).contains( "was not typed as an allowable function return type" );
74+
}
75+
} );
76+
}
77+
78+
@Test
79+
public void testCorrectDynamicInstantiation(SessionFactoryScope scope) {
80+
scope.inTransaction( session -> {
81+
final DataProjection result = session.createQuery( String.format(
82+
"select new %s(e, li) from TestEntity e join e.listItems li " +
83+
"where li.id = (select max(li2.id) from e.listItems li2)",
84+
DataProjection.class.getName()
85+
), DataProjection.class ).getSingleResult();
86+
assertThat( result.getListItem().getName() ).isEqualTo( "item_2" );
87+
} );
88+
}
89+
90+
@Entity( name = "TestEntity" )
91+
public static class TestEntity {
92+
@Id
93+
@GeneratedValue
94+
private Long id;
95+
96+
@OneToMany( fetch = FetchType.LAZY, mappedBy = "entity" )
97+
private List<ListItem> listItems;
98+
99+
public List<ListItem> getListItems() {
100+
return listItems;
101+
}
102+
}
103+
104+
@Entity( name = "ListItem" )
105+
public static class ListItem {
106+
@Id
107+
private Long id;
108+
109+
private String name;
110+
111+
@ManyToOne( fetch = FetchType.LAZY )
112+
@JoinColumn( name = "entity_id" )
113+
private TestEntity entity;
114+
115+
public ListItem() {
116+
}
117+
118+
public ListItem(Long id, String name, TestEntity entity) {
119+
this.id = id;
120+
this.name = name;
121+
this.entity = entity;
122+
}
123+
124+
public String getName() {
125+
return name;
126+
}
127+
128+
public TestEntity getEntity() {
129+
return entity;
130+
}
131+
}
132+
133+
public static class DataProjection {
134+
private final TestEntity entity;
135+
136+
private final ListItem listItem;
137+
138+
public DataProjection(TestEntity entity, ListItem listItem) {
139+
this.entity = entity;
140+
this.listItem = listItem;
141+
}
142+
143+
public TestEntity getEntity() {
144+
return entity;
145+
}
146+
147+
public ListItem getListItem() {
148+
return listItem;
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)