Skip to content

Commit 2c4584a

Browse files
committed
HHH-19857 When one of the lazy attributes is null the other ones may not get initialized correctly
1 parent f36b06c commit 2c4584a

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.mapping.lazytoone;
6+
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.FetchType;
9+
import jakarta.persistence.Id;
10+
import jakarta.persistence.JoinColumn;
11+
import jakarta.persistence.OneToOne;
12+
import org.hibernate.Hibernate;
13+
import org.hibernate.annotations.LazyGroup;
14+
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
15+
import org.hibernate.testing.bytecode.enhancement.extension.BytecodeEnhanced;
16+
import org.hibernate.testing.orm.junit.DomainModel;
17+
import org.hibernate.testing.orm.junit.SessionFactory;
18+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
19+
import org.junit.jupiter.api.AfterEach;
20+
import org.junit.jupiter.api.Test;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
24+
@DomainModel(
25+
annotatedClasses = {
26+
LazyOneToOneWithCastTest.ContainingEntity.class,
27+
LazyOneToOneWithCastTest.ContainedEntity.class,
28+
}
29+
)
30+
@SessionFactory
31+
@BytecodeEnhanced
32+
@EnhancementOptions(lazyLoading = true)
33+
class LazyOneToOneWithCastTest {
34+
35+
@Test
36+
void oneNullOneNotNull(SessionFactoryScope scope) {
37+
scope.inTransaction( session -> {
38+
ContainingEntity containingEntity1 = new ContainingEntity();
39+
containingEntity1.setId( 2 );
40+
41+
ContainedEntity contained1 = new ContainedEntity();
42+
contained1.setId( 4 );
43+
contained1.setContainingAsIndexedEmbeddedWithCast( containingEntity1 );
44+
containingEntity1.setContainedIndexedEmbeddedWithCast( contained1 );
45+
46+
session.persist( contained1 );
47+
session.persist( containingEntity1 );
48+
49+
} );
50+
51+
scope.inTransaction( session -> {
52+
ContainedEntity contained = session.find( ContainedEntity.class, 4 );
53+
54+
ContainingEntity containingAsIndexedEmbedded = contained.getContainingAsIndexedEmbedded();
55+
assertThat( containingAsIndexedEmbedded ).isNull();
56+
assertThat( Hibernate.isPropertyInitialized( contained, "containingAsIndexedEmbedded" ) ).isTrue();
57+
assertThat( Hibernate.isPropertyInitialized( contained, "containingAsIndexedEmbeddedWithCast" ) ).isFalse();
58+
59+
Object containingAsIndexedEmbeddedWithCast = contained.getContainingAsIndexedEmbeddedWithCast();
60+
assertThat( Hibernate.isPropertyInitialized( contained, "containingAsIndexedEmbeddedWithCast" ) ).isTrue();
61+
assertThat( containingAsIndexedEmbeddedWithCast ).isNotNull();
62+
} );
63+
64+
scope.inTransaction( session -> {
65+
ContainedEntity contained = session.find( ContainedEntity.class, 4 );
66+
assertThat( contained.getContainingAsIndexedEmbeddedWithCast() ).isNotNull();
67+
} );
68+
}
69+
70+
@AfterEach
71+
void tearDown(SessionFactoryScope scope) {
72+
scope.getSessionFactory().getSchemaManager().truncateMappedObjects();
73+
}
74+
75+
@Entity(name = "containing")
76+
public static class ContainingEntity {
77+
78+
@Id
79+
private Integer id;
80+
81+
@OneToOne
82+
private ContainedEntity containedIndexedEmbedded;
83+
84+
@OneToOne(targetEntity = ContainedEntity.class)
85+
@JoinColumn(name = "CIndexedEmbeddedCast")
86+
private ContainedEntity containedIndexedEmbeddedWithCast;
87+
88+
89+
public Integer getId() {
90+
return id;
91+
}
92+
93+
public void setId(Integer id) {
94+
this.id = id;
95+
}
96+
97+
public ContainedEntity getContainedIndexedEmbedded() {
98+
return containedIndexedEmbedded;
99+
}
100+
101+
public Object getContainedIndexedEmbeddedWithCast() {
102+
return containedIndexedEmbeddedWithCast;
103+
}
104+
105+
public void setContainedIndexedEmbeddedWithCast(ContainedEntity containedIndexedEmbeddedWithCast) {
106+
this.containedIndexedEmbeddedWithCast = containedIndexedEmbeddedWithCast;
107+
}
108+
109+
public void setContainedIndexedEmbedded(ContainedEntity containedIndexedEmbedded) {
110+
this.containedIndexedEmbedded = containedIndexedEmbedded;
111+
}
112+
}
113+
114+
@Entity(name = "contained")
115+
public static class ContainedEntity {
116+
@Id
117+
private Integer id;
118+
119+
@OneToOne(mappedBy = "containedIndexedEmbeddedWithCast", targetEntity = ContainingEntity.class,
120+
fetch = FetchType.LAZY)
121+
@LazyGroup("containingAsIndexedEmbeddedWithCast")
122+
private ContainingEntity containingAsIndexedEmbeddedWithCast;
123+
124+
@OneToOne(mappedBy = "containedIndexedEmbedded", fetch = FetchType.LAZY)
125+
@LazyGroup("containingAsIndexedEmbedded")
126+
private ContainingEntity containingAsIndexedEmbedded;
127+
128+
public Integer getId() {
129+
return id;
130+
}
131+
132+
public void setId(Integer id) {
133+
this.id = id;
134+
}
135+
136+
public ContainingEntity getContainingAsIndexedEmbedded() {
137+
return containingAsIndexedEmbedded;
138+
}
139+
140+
public Object getContainingAsIndexedEmbeddedWithCast() {
141+
return containingAsIndexedEmbeddedWithCast;
142+
}
143+
144+
public void setContainingAsIndexedEmbeddedWithCast(ContainingEntity containingAsIndexedEmbeddedWithCast) {
145+
this.containingAsIndexedEmbeddedWithCast = containingAsIndexedEmbeddedWithCast;
146+
}
147+
148+
public void setContainingAsIndexedEmbedded(ContainingEntity containingAsIndexedEmbedded) {
149+
this.containingAsIndexedEmbedded = containingAsIndexedEmbedded;
150+
}
151+
}
152+
}

0 commit comments

Comments
 (0)