Skip to content

Commit 1afd01a

Browse files
committed
HHH-15271 Add test for issue
1 parent c959c0b commit 1afd01a

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.entitygraph;
6+
7+
import jakarta.persistence.CascadeType;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.FetchType;
10+
import jakarta.persistence.Id;
11+
import jakarta.persistence.NamedAttributeNode;
12+
import jakarta.persistence.NamedEntityGraph;
13+
import jakarta.persistence.OneToOne;
14+
import jakarta.persistence.Table;
15+
import org.hibernate.Hibernate;
16+
import org.hibernate.Session;
17+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
18+
import org.hibernate.testing.orm.junit.JiraKey;
19+
import org.hibernate.testing.orm.junit.Jpa;
20+
import org.junit.jupiter.api.BeforeAll;
21+
import org.junit.jupiter.api.Test;
22+
23+
import java.util.Collections;
24+
25+
import static org.hibernate.jpa.SpecHints.HINT_SPEC_LOAD_GRAPH;
26+
import static org.junit.jupiter.api.Assertions.assertFalse;
27+
import static org.junit.jupiter.api.Assertions.assertTrue;
28+
29+
@Jpa(
30+
annotatedClasses = {
31+
LoadGraphMergeTest.Information.class,
32+
LoadGraphMergeTest.File.class,
33+
LoadGraphMergeTest.Content.class,
34+
}
35+
)
36+
@JiraKey( "HHH-15271" )
37+
public class LoadGraphMergeTest {
38+
39+
private static final Long INFORMATION_ID_1 = 1L;
40+
private static final Long INFORMATION_ID_2 = 2L;
41+
42+
@BeforeAll
43+
public static void init(EntityManagerFactoryScope scope) {
44+
scope.inTransaction(
45+
entityManager -> {
46+
Content content = new Content( 1L, "test content" );
47+
File file = new File( 1L, content );
48+
Information information = new Information( INFORMATION_ID_1, file );
49+
entityManager.persist( information );
50+
51+
Content content2 = new Content( 2L, "test content" );
52+
File file2 = new File( 2L, content2 );
53+
Information information2 = new Information( INFORMATION_ID_2, file2 );
54+
entityManager.persist( information2 );
55+
}
56+
);
57+
}
58+
59+
@Test
60+
public void testContentHasNotBeenInitializedByMerge(EntityManagerFactoryScope scope) {
61+
Information information1 = scope.fromTransaction( entityManager ->
62+
entityManager.find(
63+
Information.class,
64+
INFORMATION_ID_1,
65+
Collections.singletonMap(
66+
HINT_SPEC_LOAD_GRAPH,
67+
entityManager.getEntityGraph( "information.file" ) ) )
68+
);
69+
70+
Information information2 = scope.fromTransaction( entityManager ->
71+
entityManager.find(
72+
Information.class,
73+
INFORMATION_ID_2,
74+
Collections.singletonMap(
75+
HINT_SPEC_LOAD_GRAPH,
76+
entityManager.getEntityGraph( "information.file" ) ) )
77+
);
78+
79+
scope.inTransaction( entityManager -> {
80+
assertTrue( Hibernate.isInitialized( information1.getFile() ) );
81+
assertFalse( Hibernate.isInitialized( information1.getFile().getContent() ) );
82+
83+
Session session = entityManager.unwrap( Session.class );
84+
85+
Information mergedInformation = session.merge( information1,
86+
entityManager.getEntityGraph( "information.file" ) );
87+
88+
File file = mergedInformation.getFile();
89+
assertTrue( Hibernate.isInitialized( file ) );
90+
assertFalse( Hibernate.isInitialized( file.getContent() ),
91+
"Merge has initialized `file.content` lazy association" );
92+
93+
assertTrue( Hibernate.isInitialized( information2.getFile() ) );
94+
assertFalse( Hibernate.isInitialized( information2.getFile().getContent() ) );
95+
96+
Information mergedInformation2 = session.merge( information2 );
97+
98+
File file2 = mergedInformation2.getFile();
99+
assertTrue( Hibernate.isInitialized( file2 ) );
100+
assertTrue( Hibernate.isInitialized( file2.getContent() ) );
101+
} );
102+
}
103+
104+
@Test
105+
public void testFileHasNotBeenInitializedByMerge(EntityManagerFactoryScope scope) {
106+
Information information = scope.fromTransaction( entityManager ->
107+
entityManager.find(
108+
Information.class,
109+
INFORMATION_ID_1 )
110+
);
111+
112+
scope.inTransaction( entityManager -> {
113+
File file1 = information.getFile();
114+
assertFalse( Hibernate.isInitialized( file1 ) );
115+
116+
Session session = entityManager.unwrap( Session.class );
117+
Information mergedInformation = session.merge( information, session.createEntityGraph( "information" ) );
118+
119+
File file = mergedInformation.getFile();
120+
assertFalse( Hibernate.isInitialized( file ),
121+
"Merge has initialized `information.file` lazy association" );
122+
} );
123+
}
124+
125+
@Entity(name = "Information")
126+
@NamedEntityGraph(
127+
name = "information.file",
128+
attributeNodes = @NamedAttributeNode("file")
129+
)
130+
@NamedEntityGraph(
131+
name = "information"
132+
)
133+
@Table(name = "INFORMATION_TABLE")
134+
public static class Information {
135+
136+
@Id
137+
private Long id;
138+
139+
private String info;
140+
141+
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
142+
private File file;
143+
144+
public Information() {
145+
}
146+
147+
public Information(Long id, File file) {
148+
this.id = id;
149+
this.file = file;
150+
}
151+
152+
public File getFile() {
153+
return file;
154+
}
155+
156+
public Long getId() {
157+
return id;
158+
}
159+
}
160+
161+
@Entity(name = "File")
162+
@Table(name = "FILE_TABLE")
163+
public static class File {
164+
165+
@Id
166+
private Long id;
167+
168+
private String name;
169+
170+
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
171+
private Content content;
172+
173+
public File() {
174+
}
175+
176+
public File(Long id, Content content) {
177+
this.id = id;
178+
this.content = content;
179+
}
180+
181+
public Content getContent() {
182+
return content;
183+
}
184+
185+
public Long getId() {
186+
return id;
187+
}
188+
}
189+
190+
@Entity(name = "Content")
191+
@Table(name = "CONTENT_TABLE")
192+
public static class Content {
193+
194+
@Id
195+
private Long id;
196+
197+
private String content;
198+
199+
public Content() {
200+
}
201+
202+
public Content(Long id, String content) {
203+
this.id = id;
204+
this.content = content;
205+
}
206+
207+
public Long getId() {
208+
return id;
209+
}
210+
211+
public String getContent() {
212+
return content;
213+
}
214+
}
215+
216+
}

0 commit comments

Comments
 (0)