Skip to content

Commit 8277ae8

Browse files
committed
HHH-17857 Add test for issue
1 parent 622a2fa commit 8277ae8

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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;
8+
9+
import java.util.HashSet;
10+
import java.util.Set;
11+
12+
import org.hibernate.testing.orm.junit.DomainModel;
13+
import org.hibernate.testing.orm.junit.Jira;
14+
import org.hibernate.testing.orm.junit.SessionFactory;
15+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
16+
import org.junit.jupiter.api.AfterAll;
17+
import org.junit.jupiter.api.BeforeAll;
18+
import org.junit.jupiter.api.Test;
19+
20+
import jakarta.persistence.CascadeType;
21+
import jakarta.persistence.Entity;
22+
import jakarta.persistence.GeneratedValue;
23+
import jakarta.persistence.Id;
24+
import jakarta.persistence.ManyToOne;
25+
import jakarta.persistence.OneToMany;
26+
import jakarta.persistence.criteria.CriteriaBuilder;
27+
import jakarta.persistence.criteria.CriteriaQuery;
28+
import jakarta.persistence.criteria.Join;
29+
import jakarta.persistence.criteria.Root;
30+
import jakarta.persistence.criteria.SetJoin;
31+
32+
import static org.assertj.core.api.Assertions.assertThat;
33+
34+
/**
35+
* @author Marco Belladelli
36+
*/
37+
@DomainModel( annotatedClasses = {
38+
QueryToManyWithNestedToOneTest.ParentEntity.class,
39+
QueryToManyWithNestedToOneTest.ValueEntity.class,
40+
QueryToManyWithNestedToOneTest.KeyEntity.class,
41+
} )
42+
@SessionFactory
43+
@Jira( "https://hibernate.atlassian.net/browse/HHH-17857" )
44+
public class QueryToManyWithNestedToOneTest {
45+
@Test
46+
public void testCriteriaQuery(SessionFactoryScope scope) {
47+
scope.inTransaction( session -> {
48+
final CriteriaBuilder cb = session.getCriteriaBuilder();
49+
final CriteriaQuery<ParentEntity> cq = cb.createQuery( ParentEntity.class );
50+
final Root<ParentEntity> root = cq.from( ParentEntity.class );
51+
final SetJoin<ParentEntity, ValueEntity> valuesJoin = root.joinSet( "values" );
52+
final Join<ValueEntity, KeyEntity> key = valuesJoin.join( "key" );
53+
final ParentEntity result = session.createQuery(
54+
cq.where( key.get( "keyValue" ).in( "key_1", "key_2" ) )
55+
).getSingleResult();
56+
assertThat( result.getValues() ).hasSize( 2 )
57+
.extracting( ValueEntity::getKey )
58+
.extracting( KeyEntity::getKeyValue )
59+
.containsOnly( "key_1", "key_2" );
60+
} );
61+
}
62+
63+
@Test
64+
public void testHQLQuery(SessionFactoryScope scope) {
65+
scope.inTransaction( session -> {
66+
final ParentEntity result = session.createQuery(
67+
"from ParentEntity p join p.values values join values.key key where key.keyValue in ('key_3')",
68+
ParentEntity.class
69+
).getSingleResult();
70+
assertThat( result.getValues() ).hasSize( 1 )
71+
.extracting( ValueEntity::getKey )
72+
.extracting( KeyEntity::getKeyValue )
73+
.containsOnly( "key_3" );
74+
} );
75+
}
76+
77+
@BeforeAll
78+
public void setUp(SessionFactoryScope scope) {
79+
scope.inTransaction( session -> {
80+
final ParentEntity parent1 = new ParentEntity();
81+
final ValueEntity value1 = new ValueEntity( parent1, new KeyEntity( "key_1" ) );
82+
session.persist( value1 );
83+
final ValueEntity value2 = new ValueEntity( parent1, new KeyEntity( "key_2" ) );
84+
session.persist( value2 );
85+
final ValueEntity value3 = new ValueEntity( new ParentEntity(), new KeyEntity( "key_3" ) );
86+
session.persist( value3 );
87+
} );
88+
}
89+
90+
@AfterAll
91+
public void tearDown(SessionFactoryScope scope) {
92+
scope.inTransaction( session -> {
93+
session.createMutationQuery( "delete from ValueEntity" ).executeUpdate();
94+
session.createMutationQuery( "delete from ParentEntity" ).executeUpdate();
95+
session.createMutationQuery( "delete from KeyEntity" ).executeUpdate();
96+
} );
97+
}
98+
99+
@Entity( name = "ParentEntity" )
100+
static class ParentEntity {
101+
@Id
102+
@GeneratedValue
103+
private Long id;
104+
105+
@OneToMany( mappedBy = "parent" )
106+
private Set<ValueEntity> values = new HashSet<>();
107+
108+
public Set<ValueEntity> getValues() {
109+
return values;
110+
}
111+
}
112+
113+
@Entity( name = "ValueEntity" )
114+
static class ValueEntity {
115+
@Id
116+
@GeneratedValue
117+
private Long id;
118+
119+
@ManyToOne( cascade = CascadeType.ALL )
120+
private ParentEntity parent;
121+
122+
@ManyToOne( cascade = CascadeType.ALL )
123+
private KeyEntity key;
124+
125+
public ValueEntity() {
126+
}
127+
128+
public ValueEntity(ParentEntity parent, KeyEntity key) {
129+
this.parent = parent;
130+
this.key = key;
131+
}
132+
133+
public KeyEntity getKey() {
134+
return key;
135+
}
136+
}
137+
138+
@Entity( name = "KeyEntity" )
139+
static class KeyEntity {
140+
@Id
141+
@GeneratedValue
142+
private Long id;
143+
144+
private String keyValue;
145+
146+
public KeyEntity() {
147+
}
148+
149+
public KeyEntity(String keyValue) {
150+
this.keyValue = keyValue;
151+
}
152+
153+
public String getKeyValue() {
154+
return keyValue;
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)