Skip to content

Commit 58b086b

Browse files
committed
HHH-19214 Created new test classes from existing, but with explictely added ID record class with unsorted components
1 parent b46d2f0 commit 58b086b

File tree

3 files changed

+523
-0
lines changed

3 files changed

+523
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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.annotations.formula;
6+
7+
import jakarta.persistence.Column;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.EnumType;
10+
import jakarta.persistence.Enumerated;
11+
import jakarta.persistence.FetchType;
12+
import jakarta.persistence.Id;
13+
import jakarta.persistence.IdClass;
14+
import jakarta.persistence.JoinColumn;
15+
import jakarta.persistence.ManyToOne;
16+
import org.hibernate.LazyInitializationException;
17+
import org.hibernate.annotations.JoinColumnOrFormula;
18+
import org.hibernate.annotations.JoinFormula;
19+
import org.hibernate.annotations.processing.Exclude;
20+
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
21+
import org.hibernate.testing.orm.junit.JiraKey;
22+
import org.junit.Test;
23+
24+
import java.io.Serializable;
25+
import java.util.List;
26+
27+
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
28+
import static org.junit.Assert.assertEquals;
29+
import static org.junit.Assert.assertNull;
30+
import static org.junit.Assert.fail;
31+
32+
@JiraKey(value = "HHH-19214")
33+
public class JoinFormulaManyToOneLazyFetchingWithIdClassTest extends BaseEntityManagerFunctionalTestCase {
34+
35+
@Override
36+
protected Class<?>[] getAnnotatedClasses() {
37+
return new Class<?>[] {
38+
Stock.class,
39+
StockCode.class,
40+
};
41+
}
42+
43+
@Override
44+
protected void afterEntityManagerFactoryBuilt() {
45+
doInJPA( this::entityManagerFactory, entityManager -> {
46+
StockCode code = new StockCode();
47+
code.setId( 1L );
48+
code.setCopeType( CodeType.TYPE_A );
49+
code.setRefNumber( "ABC" );
50+
entityManager.persist( code );
51+
52+
Stock stock1 = new Stock();
53+
stock1.setId( 1L );
54+
stock1.setCode( code );
55+
entityManager.persist( stock1 );
56+
57+
Stock stock2 = new Stock();
58+
stock2.setId( 2L );
59+
entityManager.persist( stock2 );
60+
} );
61+
}
62+
63+
@Test
64+
public void testLazyLoading() {
65+
List<Stock> stocks = doInJPA( this::entityManagerFactory, entityManager -> {
66+
return entityManager.createQuery(
67+
"SELECT s FROM Stock s", Stock.class )
68+
.getResultList();
69+
} );
70+
assertEquals( 2, stocks.size() );
71+
72+
try {
73+
assertEquals( "ABC", stocks.get( 0 ).getCode().getRefNumber() );
74+
75+
fail( "Should have thrown LazyInitializationException" );
76+
}
77+
catch (LazyInitializationException expected) {
78+
79+
}
80+
}
81+
82+
@Test
83+
public void testEagerLoading() {
84+
doInJPA( this::entityManagerFactory, entityManager -> {
85+
List<Stock> stocks = entityManager.createQuery(
86+
"SELECT s FROM Stock s", Stock.class )
87+
.getResultList();
88+
89+
assertEquals( 2, stocks.size() );
90+
assertEquals( "ABC", stocks.get( 0 ).getCode().getRefNumber() );
91+
92+
// In 5.x, for some reason, we didn't understand that a component is a FK,
93+
// hence a partial null was wrongly handled, but in 6.0 we handle this in a unified way
94+
assertNull( stocks.get( 1 ).getCode() );
95+
} );
96+
}
97+
98+
@Entity(name = "Stock")
99+
@Exclude
100+
public static class Stock implements Serializable {
101+
102+
@Id
103+
@Column(name = "ID")
104+
private Long id;
105+
106+
@ManyToOne(fetch = FetchType.LAZY)
107+
@JoinColumnOrFormula(column = @JoinColumn(name = "CODE_ID", referencedColumnName = "ID"))
108+
@JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = "TYPE", value = "'TYPE_A'"))
109+
private StockCode code;
110+
111+
public Long getId() {
112+
return id;
113+
}
114+
115+
public void setId(Long id) {
116+
this.id = id;
117+
}
118+
119+
public StockCode getCode() {
120+
return code;
121+
}
122+
123+
public void setCode(StockCode code) {
124+
this.code = code;
125+
}
126+
}
127+
128+
@Entity(name = "StockCode")
129+
@IdClass(StockCode.ID.class)
130+
@Exclude
131+
public static class StockCode implements Serializable {
132+
133+
@Id
134+
@Column(name = "ID")
135+
private Long id;
136+
137+
@Id
138+
@Enumerated(EnumType.STRING)
139+
@Column(name = "TYPE")
140+
private CodeType copeType;
141+
142+
private String refNumber;
143+
144+
public Long getId() {
145+
return id;
146+
}
147+
148+
public void setId(Long id) {
149+
this.id = id;
150+
}
151+
152+
public CodeType getCopeType() {
153+
return copeType;
154+
}
155+
156+
public void setCopeType(CodeType copeType) {
157+
this.copeType = copeType;
158+
}
159+
160+
public String getRefNumber() {
161+
return refNumber;
162+
}
163+
164+
public void setRefNumber(String refNumber) {
165+
this.refNumber = refNumber;
166+
}
167+
168+
public record ID(Long id, CodeType copeType) {}
169+
}
170+
171+
public enum CodeType {
172+
TYPE_A, TYPE_B;
173+
}
174+
175+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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.annotations.formula;
6+
7+
import jakarta.persistence.Column;
8+
import jakarta.persistence.Entity;
9+
import jakarta.persistence.EnumType;
10+
import jakarta.persistence.Enumerated;
11+
import jakarta.persistence.FetchType;
12+
import jakarta.persistence.Id;
13+
import jakarta.persistence.IdClass;
14+
import jakarta.persistence.JoinColumn;
15+
import jakarta.persistence.ManyToOne;
16+
import org.hibernate.annotations.JoinColumnOrFormula;
17+
import org.hibernate.annotations.JoinFormula;
18+
import org.hibernate.annotations.NotFound;
19+
import org.hibernate.annotations.NotFoundAction;
20+
import org.hibernate.annotations.processing.Exclude;
21+
import org.hibernate.boot.model.internal.ToOneBinder;
22+
import org.hibernate.internal.CoreMessageLogger;
23+
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
24+
import org.hibernate.testing.logger.LoggerInspectionRule;
25+
import org.hibernate.testing.logger.Triggerable;
26+
import org.hibernate.testing.orm.junit.JiraKey;
27+
import org.jboss.logging.Logger;
28+
import org.junit.Rule;
29+
import org.junit.Test;
30+
31+
import java.io.Serializable;
32+
import java.lang.invoke.MethodHandles;
33+
import java.util.List;
34+
35+
import static org.assertj.core.api.Assertions.assertThat;
36+
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
37+
import static org.junit.Assert.assertEquals;
38+
import static org.junit.Assert.assertNull;
39+
40+
@JiraKey(value = "HHH-19214")
41+
public class JoinFormulaManyToOneNotIgnoreLazyFetchingWithIdClassTest extends BaseEntityManagerFunctionalTestCase {
42+
43+
@Rule
44+
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
45+
Logger.getMessageLogger( MethodHandles.lookup(), CoreMessageLogger.class, ToOneBinder.class.getName() )
46+
);
47+
48+
private final Triggerable triggerable = logInspection.watchForLogMessages( "HHH000491" );
49+
50+
51+
@Override
52+
protected Class<?>[] getAnnotatedClasses() {
53+
return new Class<?>[] {
54+
Stock.class,
55+
StockCode.class,
56+
};
57+
}
58+
59+
@Override
60+
protected void afterEntityManagerFactoryBuilt() {
61+
doInJPA( this::entityManagerFactory, entityManager -> {
62+
StockCode code = new StockCode();
63+
code.setId( 1L );
64+
code.setCopeType( CodeType.TYPE_A );
65+
code.setRefNumber( "ABC" );
66+
entityManager.persist( code );
67+
68+
Stock stock1 = new Stock();
69+
stock1.setId( 1L );
70+
stock1.setCode( code );
71+
entityManager.persist( stock1 );
72+
73+
Stock stock2 = new Stock();
74+
stock2.setId( 2L );
75+
entityManager.persist( stock2 );
76+
} );
77+
}
78+
79+
@Test
80+
public void testLazyLoading() {
81+
assertThat( triggerable.wasTriggered() )
82+
.describedAs( "Expecting WARN message to be logged" )
83+
.isTrue();
84+
85+
List<Stock> stocks = doInJPA( this::entityManagerFactory, entityManager -> {
86+
return entityManager.createQuery(
87+
"SELECT s FROM Stock s", Stock.class )
88+
.getResultList();
89+
} );
90+
assertEquals( 2, stocks.size() );
91+
92+
assertEquals( "ABC", stocks.get( 0 ).getCode().getRefNumber() );
93+
assertNull( stocks.get( 1 ).getCode() );
94+
}
95+
96+
@Entity(name = "Stock")
97+
@Exclude
98+
public static class Stock implements Serializable {
99+
100+
@Id
101+
@Column(name = "ID")
102+
private Long id;
103+
104+
@ManyToOne(fetch = FetchType.LAZY)
105+
@NotFound(action = NotFoundAction.IGNORE)
106+
@JoinColumnOrFormula(column = @JoinColumn(name = "CODE_ID", referencedColumnName = "ID"))
107+
@JoinColumnOrFormula(formula = @JoinFormula(referencedColumnName = "TYPE", value = "'TYPE_A'"))
108+
private StockCode code;
109+
110+
public Long getId() {
111+
return id;
112+
}
113+
114+
public void setId(Long id) {
115+
this.id = id;
116+
}
117+
118+
public StockCode getCode() {
119+
return code;
120+
}
121+
122+
public void setCode(StockCode code) {
123+
this.code = code;
124+
}
125+
}
126+
127+
@Entity(name = "StockCode")
128+
@IdClass(StockCode.ID.class)
129+
@Exclude
130+
public static class StockCode implements Serializable {
131+
132+
@Id
133+
@Column(name = "ID")
134+
private Long id;
135+
136+
@Id
137+
@Enumerated(EnumType.STRING)
138+
@Column(name = "TYPE")
139+
private CodeType copeType;
140+
141+
private String refNumber;
142+
143+
public Long getId() {
144+
return id;
145+
}
146+
147+
public void setId(Long id) {
148+
this.id = id;
149+
}
150+
151+
public CodeType getCopeType() {
152+
return copeType;
153+
}
154+
155+
public void setCopeType(CodeType copeType) {
156+
this.copeType = copeType;
157+
}
158+
159+
public String getRefNumber() {
160+
return refNumber;
161+
}
162+
163+
public void setRefNumber(String refNumber) {
164+
this.refNumber = refNumber;
165+
}
166+
167+
public record ID(Long id, CodeType copeType) {}
168+
}
169+
170+
public enum CodeType {
171+
TYPE_A, TYPE_B;
172+
}
173+
174+
}

0 commit comments

Comments
 (0)