Skip to content

Commit 4518f3d

Browse files
Matej Pucihardreab8
authored andcommitted
HHH-18565 reproduce issue
1 parent 952cf53 commit 4518f3d

File tree

1 file changed

+378
-0
lines changed

1 file changed

+378
-0
lines changed
Lines changed: 378 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
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.bytecode.enhancement.basic;
8+
9+
import java.util.HashSet;
10+
import java.util.Set;
11+
12+
import org.hibernate.cfg.AvailableSettings;
13+
14+
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
15+
import org.hibernate.testing.orm.junit.DomainModel;
16+
import org.hibernate.testing.orm.junit.JiraKey;
17+
import org.hibernate.testing.orm.junit.ServiceRegistry;
18+
import org.hibernate.testing.orm.junit.SessionFactory;
19+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
20+
import org.hibernate.testing.orm.junit.Setting;
21+
import org.junit.jupiter.api.AfterAll;
22+
import org.junit.jupiter.api.BeforeAll;
23+
import org.junit.jupiter.api.Test;
24+
25+
import jakarta.persistence.Entity;
26+
import jakarta.persistence.FetchType;
27+
import jakarta.persistence.GeneratedValue;
28+
import jakarta.persistence.Id;
29+
import jakarta.persistence.JoinColumn;
30+
import jakarta.persistence.ManyToOne;
31+
import jakarta.persistence.MappedSuperclass;
32+
import jakarta.persistence.OneToMany;
33+
34+
import static org.assertj.core.api.Assertions.assertThat;
35+
36+
@DomainModel(
37+
annotatedClasses = {
38+
ReloadAssociatedEntitiesTest.SimpleOne.class,
39+
ReloadAssociatedEntitiesTest.SimpleTwo.class,
40+
ReloadAssociatedEntitiesTest.SimpleThree.class,
41+
ReloadAssociatedEntitiesTest.ConcreteOne.class,
42+
ReloadAssociatedEntitiesTest.ConcreteTwo.class,
43+
ReloadAssociatedEntitiesTest.ConcreteThree.class,
44+
ReloadAssociatedEntitiesTest.AbsOne.class,
45+
ReloadAssociatedEntitiesTest.AbsTwo.class,
46+
}
47+
)
48+
@ServiceRegistry(
49+
settings = {
50+
@Setting(name = AvailableSettings.USE_SECOND_LEVEL_CACHE, value = "false"),
51+
@Setting(name = AvailableSettings.ENABLE_LAZY_LOAD_NO_TRANS, value = "true"),
52+
}
53+
)
54+
@SessionFactory
55+
@BytecodeEnhanced
56+
@JiraKey("HHH-18565")
57+
public class ReloadAssociatedEntitiesTest {
58+
59+
private Long oneId;
60+
private Long threeId;
61+
private Long simpleOneId;
62+
private Long simpleThreeId;
63+
64+
@BeforeAll
65+
public void before(SessionFactoryScope scope) {
66+
scope.inTransaction( s -> {
67+
final var one = new ConcreteOne();
68+
final var two = new ConcreteTwo();
69+
final var three = new ConcreteThree();
70+
one.setTwo( two );
71+
two.getOnes().add( one );
72+
two.setThree( three );
73+
three.getTwos().add( two );
74+
75+
s.persist( one );
76+
s.persist( two );
77+
s.persist( three );
78+
oneId = one.getId();
79+
threeId = three.getId();
80+
81+
final var simpleOne = new SimpleOne();
82+
final var simpleTwo = new SimpleTwo();
83+
final var simpleThree = new SimpleThree();
84+
simpleOne.setTwo( simpleTwo );
85+
simpleTwo.getOnes().add( simpleOne );
86+
simpleTwo.setThree( simpleThree );
87+
simpleThree.getTwos().add( simpleTwo );
88+
89+
s.persist( simpleOne );
90+
s.persist( simpleTwo );
91+
s.persist( simpleThree );
92+
simpleOneId = simpleOne.getId();
93+
simpleThreeId = simpleThree.getId();
94+
} );
95+
}
96+
97+
@AfterAll
98+
void after(SessionFactoryScope scope) {
99+
scope.inTransaction( session -> {
100+
session.createMutationQuery( session.getCriteriaBuilder().createCriteriaDelete( ConcreteOne.class ) )
101+
.executeUpdate();
102+
session.createMutationQuery( session.getCriteriaBuilder().createCriteriaDelete( ConcreteTwo.class ) )
103+
.executeUpdate();
104+
session.createMutationQuery( session.getCriteriaBuilder().createCriteriaDelete( ConcreteThree.class ) )
105+
.executeUpdate();
106+
} );
107+
}
108+
109+
//--THIS IS THE REPRODUCER--//
110+
@Test
111+
public void reloadToOneFromSimpleEntity(SessionFactoryScope scope) {
112+
scope.inTransaction( s -> {
113+
SimpleOne one = s.createQuery(
114+
"select o from SimpleOne o join fetch o.two t where o.id = :oneId",
115+
SimpleOne.class
116+
)
117+
.setParameter( "oneId", simpleOneId ).getSingleResult();
118+
119+
SimpleOne one2 = s.createQuery(
120+
"select o from SimpleOne o join fetch o.two t join fetch t.three rh where o.id = :oneId",
121+
SimpleOne.class
122+
)
123+
.setParameter( "oneId", simpleOneId ).getSingleResult();
124+
125+
assertThat( one2 ).isNotNull();
126+
} );
127+
}
128+
//--THIS IS THE REPRODUCER--//
129+
130+
//--FUTURE PROOF--//
131+
@Test
132+
public void reloadToOneFromParameterizedEntity(SessionFactoryScope scope) {
133+
scope.inTransaction( s -> {
134+
ConcreteOne one = s.createQuery(
135+
"select o from ConcreteOne o join fetch o.two t where o.id = :oneId",
136+
ConcreteOne.class
137+
)
138+
.setParameter( "oneId", oneId ).getSingleResult();
139+
140+
ConcreteOne one2 = s.createQuery(
141+
"select o from ConcreteOne o join fetch o.two t join fetch t.three rh where o.id = :oneId",
142+
ConcreteOne.class
143+
)
144+
.setParameter( "oneId", oneId ).getSingleResult();
145+
146+
assertThat( one2 ).isNotNull();
147+
} );
148+
}
149+
150+
@Test
151+
public void reloadToManyFromParameterizedEntity(SessionFactoryScope scope) {
152+
scope.inTransaction( s -> {
153+
ConcreteThree three = s.createQuery(
154+
"select t from ConcreteThree t join t.twos tw where t.id = :threeId",
155+
ConcreteThree.class
156+
)
157+
.setParameter( "threeId", threeId ).getSingleResult();
158+
159+
ConcreteThree three1 = s.createQuery(
160+
"select t from ConcreteThree t join fetch t.twos tw join fetch tw.ones o where t.id = :threeId",
161+
ConcreteThree.class
162+
)
163+
.setParameter( "threeId", threeId ).getSingleResult();
164+
165+
assertThat( three1 ).isNotNull();
166+
} );
167+
}
168+
169+
@Test
170+
public void reloadToManyFromSimpleEntity(SessionFactoryScope scope) {
171+
scope.inTransaction( s -> {
172+
SimpleThree three = s.createQuery(
173+
"select t from SimpleThree t join t.twos tw where t.id = :threeId",
174+
SimpleThree.class
175+
)
176+
.setParameter( "threeId", simpleThreeId ).getSingleResult();
177+
178+
SimpleThree three1 = s.createQuery(
179+
"select t from SimpleThree t join fetch t.twos tw join fetch tw.ones o where t.id = :threeId",
180+
SimpleThree.class
181+
)
182+
.setParameter( "threeId", simpleThreeId ).getSingleResult();
183+
184+
assertThat( three1 ).isNotNull();
185+
} );
186+
}
187+
//--FUTURE PROOF--//
188+
189+
@Entity(name = "ConcreteOne")
190+
public static class ConcreteOne extends AbsOne<ConcreteTwo> {
191+
}
192+
193+
@MappedSuperclass
194+
public static abstract class AbsOne<TWO extends AbsTwo<?, ?>> {
195+
@Id
196+
@GeneratedValue
197+
private Long id;
198+
199+
@ManyToOne(fetch = FetchType.LAZY)
200+
@JoinColumn(name = "two_id")
201+
private TWO two;
202+
203+
public Long getId() {
204+
return id;
205+
}
206+
207+
public void setId(Long id) {
208+
this.id = id;
209+
}
210+
211+
public TWO getTwo() {
212+
return two;
213+
}
214+
215+
public void setTwo(TWO two) {
216+
this.two = two;
217+
}
218+
}
219+
220+
@Entity(name = "ConcreteTwo")
221+
public static class ConcreteTwo extends AbsTwo<ConcreteOne, ConcreteThree> {
222+
}
223+
224+
@MappedSuperclass
225+
public static abstract class AbsTwo<ONE extends AbsOne<?>, THREE> {
226+
@Id
227+
@GeneratedValue
228+
private Long id;
229+
230+
@ManyToOne(fetch = FetchType.LAZY)
231+
@JoinColumn(name = "three_id")
232+
private THREE three;
233+
234+
@OneToMany(mappedBy = "two")
235+
private Set<ONE> ones = new HashSet<>();
236+
237+
public Long getId() {
238+
return id;
239+
}
240+
241+
public void setId(Long id) {
242+
this.id = id;
243+
}
244+
245+
public THREE getThree() {
246+
return three;
247+
}
248+
249+
public void setThree(THREE three) {
250+
this.three = three;
251+
}
252+
253+
public Set<ONE> getOnes() {
254+
return ones;
255+
}
256+
257+
public void setOnes(Set<ONE> ones) {
258+
this.ones = ones;
259+
}
260+
}
261+
262+
@Entity(name = "ConcreteThree")
263+
public static class ConcreteThree {
264+
@Id
265+
@GeneratedValue
266+
private Long id;
267+
268+
@OneToMany(mappedBy = "three")
269+
private Set<ConcreteTwo> twos = new HashSet<>();
270+
271+
public Long getId() {
272+
return id;
273+
}
274+
275+
public void setId(Long id) {
276+
this.id = id;
277+
}
278+
279+
public Set<ConcreteTwo> getTwos() {
280+
return twos;
281+
}
282+
283+
public void setTwos(Set<ConcreteTwo> twos) {
284+
this.twos = twos;
285+
}
286+
}
287+
288+
@Entity(name = "SimpleOne")
289+
public static class SimpleOne {
290+
@Id
291+
@GeneratedValue
292+
private Long id;
293+
294+
@ManyToOne(fetch = FetchType.LAZY)
295+
@JoinColumn(name = "two_id")
296+
private SimpleTwo two;
297+
298+
public Long getId() {
299+
return id;
300+
}
301+
302+
public void setId(Long id) {
303+
this.id = id;
304+
}
305+
306+
public SimpleTwo getTwo() {
307+
return two;
308+
}
309+
310+
public void setTwo(SimpleTwo two) {
311+
this.two = two;
312+
}
313+
}
314+
315+
@Entity(name = "SimpleTwo")
316+
public static class SimpleTwo {
317+
@Id
318+
@GeneratedValue
319+
private Long id;
320+
321+
@ManyToOne(fetch = FetchType.LAZY)
322+
@JoinColumn(name = "three_id")
323+
private SimpleThree three;
324+
325+
@OneToMany(mappedBy = "two")
326+
private Set<SimpleOne> ones = new HashSet<>();
327+
328+
public Long getId() {
329+
return id;
330+
}
331+
332+
public void setId(Long id) {
333+
this.id = id;
334+
}
335+
336+
public SimpleThree getThree() {
337+
return three;
338+
}
339+
340+
public void setThree(SimpleThree three) {
341+
this.three = three;
342+
}
343+
344+
public Set<SimpleOne> getOnes() {
345+
return ones;
346+
}
347+
348+
public void setOnes(Set<SimpleOne> ones) {
349+
this.ones = ones;
350+
}
351+
}
352+
353+
@Entity(name = "SimpleThree")
354+
public static class SimpleThree {
355+
@Id
356+
@GeneratedValue
357+
private Long id;
358+
359+
@OneToMany(mappedBy = "three")
360+
private Set<SimpleTwo> twos = new HashSet<>();
361+
362+
public Long getId() {
363+
return id;
364+
}
365+
366+
public void setId(Long id) {
367+
this.id = id;
368+
}
369+
370+
public Set<SimpleTwo> getTwos() {
371+
return twos;
372+
}
373+
374+
public void setTwos(Set<SimpleTwo> twos) {
375+
this.twos = twos;
376+
}
377+
}
378+
}

0 commit comments

Comments
 (0)