Skip to content

Commit 14d05e1

Browse files
committed
Cleaning up names, order and JavaDoc.
1 parent 1ccc7ee commit 14d05e1

File tree

1 file changed

+60
-47
lines changed

1 file changed

+60
-47
lines changed

src/test/java/org/hibernate/bugs/JPAUnitTestCase.java

+60-47
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
package org.hibernate.bugs;
22

3-
import org.assertj.core.api.Assertions;
43
import org.hibernate.Hibernate;
54
import org.junit.After;
65
import org.junit.Before;
6+
import org.junit.Ignore;
77
import org.junit.Test;
88

99
import javax.persistence.EntityManager;
1010
import javax.persistence.EntityManagerFactory;
1111
import javax.persistence.Persistence;
12-
import javax.persistence.Query;
1312
import javax.persistence.TypedQuery;
1413
import javax.persistence.criteria.CriteriaBuilder;
1514
import javax.persistence.criteria.CriteriaQuery;
16-
import javax.persistence.criteria.Fetch;
1715
import javax.persistence.criteria.Join;
1816
import javax.persistence.criteria.JoinType;
1917
import javax.persistence.criteria.Root;
2018
import java.util.List;
2119
import java.util.function.Consumer;
22-
import java.util.function.Function;
23-
import java.util.function.Supplier;
2420

2521
import static org.assertj.core.api.Assertions.*;
2622

@@ -43,11 +39,13 @@ public void destroy() {
4339
}
4440

4541
/**
46-
* A condition on a join limits the resulting parent entity, but not their referenced entities.
47-
* Since the children relation is lazy and no fetch join was specified the children property is not initialized.
42+
* Simple Join does not fetch joined attribute.
43+
* Children are complete.
44+
* <p>
45+
* JPQL.
4846
*/
4947
@Test
50-
public void selectJoinWithSimpleCondition() {
48+
public void simpleJoinDoesNotFetchAttributeJpql() {
5149
inTransaction(em -> {
5250

5351
final TypedQuery<Parent> query = em.createQuery(
@@ -64,11 +62,13 @@ public void selectJoinWithSimpleCondition() {
6462
}
6563

6664
/**
67-
* A condition on a join limits the resulting parent entity, but not their referenced entities.
68-
* Since the children relation is lazy and no fetch join was specified the children property is not initialized.
65+
* Simple Join does not fetch joined attribute.
66+
* Children are complete.
67+
* <p>
68+
* Criteria API.
6969
*/
7070
@Test
71-
public void selectJoinWithSimpleConditionCriteria() {
71+
public void selectJoinWithSimpleConditionCriteriaApi() {
7272
inTransaction(em -> {
7373

7474
final CriteriaBuilder cb = em.getCriteriaBuilder();
@@ -88,12 +88,14 @@ public void selectJoinWithSimpleConditionCriteria() {
8888

8989
/**
9090
* This not a fetch join as described in the specification.
91-
*
91+
* <p>
9292
* It does limit the returned parent, but also limits the contained children.
9393
* Since it is a fetch join the children list is initialized.
94+
* <p>
95+
* By this usage a FETCH JOIN is a JOIN.
9496
*/
9597
@Test
96-
public void selectJoinFetchWithSimpleCondition() {
98+
public void fetchJoinUsedInCoditionLimitsResultsJpql() {
9799

98100
inTransaction(em -> {
99101

@@ -110,12 +112,15 @@ public void selectJoinFetchWithSimpleCondition() {
110112
}
111113

112114
/**
113-
* This not a fetch join as described in the specification.
114-
*
115-
* And it is not expressable in Criteria API
115+
* One actually can use a fetch join as a join in the Criteria API if one casts the {@link javax.persistence.criteria.Fetch} to {@link Join}.
116+
* <p>
117+
* This is highly brittle since it depends on implementation details.
118+
* <p>
119+
* It does limit the returned parent, but also limits the contained children.
120+
* Since it is a fetch join the children list is initialized.
116121
*/
117122
@Test
118-
public void selectJoinFetchWithSimpleConditionCriteria() {
123+
public void fetchJoinUsedInCoditionHackedLimitsResultsCriteriaApi() {
119124

120125
inTransaction(em -> {
121126

@@ -138,10 +143,35 @@ public void selectJoinFetchWithSimpleConditionCriteria() {
138143
}
139144

140145
/**
146+
* One cannot use a path expression to silently reuse a fetch with Criteria API. The test fails when executed.
147+
*/
148+
@Test
149+
@Ignore
150+
public void fetchJoinUsedInCoditionFailsCriterApi() {
151+
152+
inTransaction(em -> {
153+
154+
final CriteriaBuilder cb = em.getCriteriaBuilder();
155+
final CriteriaQuery<Parent> query = cb.createQuery(Parent.class);
156+
final Root<Parent> root = query.from(Parent.class);
157+
root.fetch("children");
158+
query.where(cb.equal(root.get("children").get("name"), "Baby Smurf"));
159+
160+
final Parent parent = em.createQuery(query).getSingleResult();
161+
162+
assertThat(parent).isNotNull();
163+
assertThat(Hibernate.isInitialized(parent.children)).isFalse();
164+
assertThat(Hibernate.isInitialized(parent.favoriteChild)).isTrue();
165+
assertThat(parent.children).hasSize(3);
166+
});
167+
}
168+
169+
/**
170+
* This is what the specification suggests to use if one wants to use a joined attribute in a condition AND wants to fetch that join as well:
141171
* Join fetch PLUS a JOIN initializes the collection and loads the children.
142172
*/
143173
@Test
144-
public void selectJoinFetchAndJoinWithSimpleConditionGet() {
174+
public void joinFetchPlusJoinWithConditionFetchesAllChildrenAndFiltersParentByChildrenJpql() {
145175

146176
inTransaction(em -> {
147177

@@ -157,11 +187,15 @@ public void selectJoinFetchAndJoinWithSimpleConditionGet() {
157187
assertThat(parent.children).hasSize(3);
158188
});
159189
}
190+
160191
/**
192+
* This is what the specification suggests to use if one wants to use a joined attribute in a condition AND wants to fetch that join as well:
161193
* Join fetch PLUS a JOIN initializes the collection and loads the children.
194+
* <p>
195+
* But when queried with {@code getResultList()} duplicates are returned.
162196
*/
163197
@Test
164-
public void selectJoinFetchAndJoinWithSimpleConditionResultList() {
198+
public void joinFetchPlusJoinWithConditionFetchesAllChildrenAndFiltersParentByChildrenResultListJpql() {
165199

166200
inTransaction(em -> {
167201

@@ -183,10 +217,11 @@ public void selectJoinFetchAndJoinWithSimpleConditionResultList() {
183217
}
184218

185219
/**
220+
* This is what the specification suggests to use if one wants to use a joined attribute in a condition AND wants to fetch that join as well:
186221
* Join fetch PLUS a JOIN initializes the collection and loads the children.
187222
*/
188223
@Test
189-
public void selectJoinFetchAndJoinWithSimpleConditionCriteria() {
224+
public void joinFetchPlusJoinWithConditionFetchesAllChildrenAndFiltersParentByChildrenJpqlCriteriaApi() {
190225

191226
inTransaction(em -> {
192227

@@ -206,33 +241,10 @@ public void selectJoinFetchAndJoinWithSimpleConditionCriteria() {
206241
}
207242

208243
/**
209-
* Join fetch PLUS a JOIN initializes the collection and loads the children.
210-
*/
211-
@Test
212-
public void selectReusingFetchWithPathExpressionWithSimpleConditionCriteria() {
213-
214-
inTransaction(em -> {
215-
216-
final CriteriaBuilder cb = em.getCriteriaBuilder();
217-
final CriteriaQuery<Parent> query = cb.createQuery(Parent.class);
218-
final Root<Parent> root = query.from(Parent.class);
219-
// root.fetch("children");
220-
query.where(cb.equal(root.get("children").get("name"), "Baby Smurf"));
221-
222-
final Parent parent = em.createQuery(query).getSingleResult();
223-
224-
assertThat(parent).isNotNull();
225-
assertThat(Hibernate.isInitialized(parent.children)).isFalse();
226-
assertThat(Hibernate.isInitialized(parent.favoriteChild)).isTrue();
227-
assertThat(parent.children).hasSize(3);
228-
});
229-
}
230-
231-
/**
232-
* Join fetch PLUS a JOIN initializes the collection and loads the children.
244+
* For * to One relations reusing a Fetch Join does not alter the result in a surprising way.
233245
*/
234246
@Test
235-
public void selectReusingFetchWithPathExpressionWithSimpleConditionCriteriaSingle() {
247+
public void fetchJoinReusedByPathExpressionForOneToOneJpqlMatch() {
236248

237249
inTransaction(em -> {
238250

@@ -251,11 +263,12 @@ public void selectReusingFetchWithPathExpressionWithSimpleConditionCriteriaSingl
251263
});
252264
}
253265

266+
254267
/**
255-
* Join fetch PLUS a JOIN initializes the collection and loads the children.
268+
* For * to One relations reusing a Fetch Join does not alter the result in a surprising way.
256269
*/
257270
@Test
258-
public void selectReusingLeftOuterFetchWithPathExpressionWithSimpleConditionCriteria() {
271+
public void fetchJoinReusedByPathExpressionForOneToOneJpqlNoMatch() {
259272

260273
inTransaction(em -> {
261274

0 commit comments

Comments
 (0)