Skip to content

Commit 4c364a1

Browse files
bukajsytlosSanne
authored andcommitted
HHH-14223 - nullpointer exception on @JoinFormula with implicit join
1 parent 14a72bc commit 4c364a1

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package org.hibernate.persister.entity;
2+
3+
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
4+
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
import javax.persistence.CascadeType;
9+
import javax.persistence.Entity;
10+
import javax.persistence.FetchType;
11+
import javax.persistence.GeneratedValue;
12+
import javax.persistence.Id;
13+
import javax.persistence.JoinColumn;
14+
import javax.persistence.ManyToOne;
15+
import javax.persistence.OneToMany;
16+
17+
import org.hibernate.annotations.JoinColumnOrFormula;
18+
import org.hibernate.annotations.JoinColumnsOrFormulas;
19+
import org.hibernate.annotations.JoinFormula;
20+
import org.hibernate.cfg.AvailableSettings;
21+
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
22+
import org.hibernate.testing.TestForIssue;
23+
import org.junit.Before;
24+
import org.junit.Test;
25+
26+
@TestForIssue(jiraKey = "HHH-14223")
27+
public class JoinFormulaImplicitJoinTest extends BaseEntityManagerFunctionalTestCase {
28+
@Override
29+
protected Class<?>[] getAnnotatedClasses() {
30+
return new Class<?>[] {
31+
Person.class, PersonVersion.class
32+
};
33+
}
34+
35+
@Override
36+
protected void addConfigOptions(Map options) {
37+
options.put(
38+
AvailableSettings.GLOBALLY_QUOTED_IDENTIFIERS,
39+
Boolean.TRUE
40+
);
41+
}
42+
43+
@Before
44+
public void setUp() {
45+
doInJPA( this::entityManagerFactory, entityManager -> {
46+
final Person person = new Person();
47+
entityManager.persist(person);
48+
49+
for (int i = 0; i < 3; i++) {
50+
final PersonVersion personVersion = new PersonVersion();
51+
personVersion.setName("Name" + i);
52+
personVersion.setVersion(i);
53+
personVersion.setPerson(person);
54+
entityManager.persist(personVersion);
55+
}
56+
});
57+
}
58+
59+
protected int entityCount() {
60+
return 5;
61+
}
62+
63+
@Test
64+
public void testImplicitJoin() {
65+
doInJPA( this::entityManagerFactory, entityManager -> {
66+
entityManager.createQuery(
67+
"SELECT person\n" +
68+
"FROM Person AS person\n" +
69+
" LEFT JOIN FETCH person.latestPersonVersion\n" +
70+
"order by person.latestPersonVersion.id desc\n"
71+
);
72+
});
73+
}
74+
75+
@Entity(name = "Person")
76+
public static class Person {
77+
78+
@Id
79+
@GeneratedValue
80+
private Long id;
81+
82+
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true)
83+
private List<PersonVersion> personVersions;
84+
85+
@ManyToOne
86+
@JoinColumnsOrFormulas({
87+
@JoinColumnOrFormula(
88+
formula = @JoinFormula(
89+
value = "(SELECT person_version.id FROM person_version WHERE person_version.person_id = id ORDER BY person_version.version DESC LIMIT 1)",
90+
referencedColumnName = "id")
91+
)
92+
})
93+
private PersonVersion latestPersonVersion;
94+
95+
public Long getId() {
96+
return id;
97+
}
98+
99+
public void setId(Long id) {
100+
this.id = id;
101+
}
102+
103+
public List<PersonVersion> getPersonVersions() {
104+
return personVersions;
105+
}
106+
107+
public void setPersonVersions(List<PersonVersion> personVersions) {
108+
this.personVersions = personVersions;
109+
}
110+
111+
public PersonVersion getLatestPersonVersion() {
112+
return latestPersonVersion;
113+
}
114+
115+
public void setLatestPersonVersion(PersonVersion latestPersonVersion) {
116+
this.latestPersonVersion = latestPersonVersion;
117+
}
118+
}
119+
120+
@Entity(name = "PersonVersion")
121+
public static class PersonVersion {
122+
123+
@Id
124+
@GeneratedValue
125+
private Long id;
126+
127+
private String name;
128+
129+
private Integer version;
130+
131+
@ManyToOne(fetch = FetchType.LAZY)
132+
@JoinColumn(name = "person_id")
133+
private Person person;
134+
135+
public Long getId() {
136+
return id;
137+
}
138+
139+
public void setId(Long id) {
140+
this.id = id;
141+
}
142+
143+
public String getName() {
144+
return name;
145+
}
146+
147+
public void setName(String name) {
148+
this.name = name;
149+
}
150+
151+
public Integer getVersion() {
152+
return version;
153+
}
154+
155+
public void setVersion(Integer version) {
156+
this.version = version;
157+
}
158+
159+
public Person getPerson() {
160+
return person;
161+
}
162+
163+
public void setPerson(Person person) {
164+
this.person = person;
165+
}
166+
}
167+
}

0 commit comments

Comments
 (0)