Skip to content

Commit 7b3b58a

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

3 files changed

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

0 commit comments

Comments
 (0)