Skip to content

Commit 82cdc82

Browse files
gbadnerdreab8
authored andcommitted
HHH-9777 : Dereferenced collections are not processed properly (test cases)
1 parent 58fd078 commit 82cdc82

11 files changed

+847
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* Copyright (c) 2015, Red Hat Inc. or third-party contributors as
5+
* indicated by the @author tags or express copyright attribution
6+
* statements applied by the authors. All third-party contributions are
7+
* distributed under license by Red Hat Inc.
8+
*
9+
* This copyrighted material is made available to anyone wishing to use, modify,
10+
* copy, or redistribute it subject to the terms and conditions of the GNU
11+
* Lesser General Public License, as published by the Free Software Foundation.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15+
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16+
* for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public License
19+
* along with this distribution; if not, write to:
20+
* Free Software Foundation, Inc.
21+
* 51 Franklin Street, Fifth Floor
22+
* Boston, MA 02110-1301 USA
23+
*/
24+
package org.hibernate.test.collection.dereferenced;
25+
26+
import org.junit.Test;
27+
28+
import org.hibernate.*;
29+
import org.hibernate.collection.internal.AbstractPersistentCollection;
30+
import org.hibernate.collection.spi.PersistentCollection;
31+
import org.hibernate.engine.spi.CollectionEntry;
32+
import org.hibernate.engine.spi.EntityEntry;
33+
import org.hibernate.engine.spi.SessionImplementor;
34+
import org.hibernate.testing.FailureExpected;
35+
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
36+
37+
import java.lang.InstantiationException;
38+
import java.util.HashSet;
39+
40+
import static org.junit.Assert.assertEquals;
41+
import static org.junit.Assert.assertNotNull;
42+
import static org.junit.Assert.assertNull;
43+
import static org.junit.Assert.assertSame;
44+
import static org.junit.Assert.assertTrue;
45+
46+
/**
47+
* @author Gail Badner
48+
*/
49+
public abstract class AbstractDereferencedCollectionTest extends BaseCoreFunctionalTestCase {
50+
51+
@Test
52+
@FailureExpected( jiraKey = "HHH-9777")
53+
public void testMergeNullCollection() {
54+
Session s = openSession();
55+
s.getTransaction().begin();
56+
One one = createOwner();
57+
assertNull( one.getManies() );
58+
s.save( one );
59+
assertNull( one.getManies() );
60+
EntityEntry eeOne = getEntityEntry( s, one );
61+
assertNull( eeOne.getLoadedValue( "manies" ) );
62+
s.flush();
63+
assertNull( one.getManies() );
64+
assertNull( eeOne.getLoadedValue( "manies" ) );
65+
s.getTransaction().commit();
66+
s.close();
67+
68+
final String role = getCollectionOwnerClass().getName() + ".manies";
69+
70+
s = openSession();
71+
s.getTransaction().begin();
72+
one = (One) s.merge( one );
73+
74+
// after merging, one.getManies() should still be null;
75+
// the EntityEntry loaded state should contain a PersistentCollection though.
76+
77+
assertNull( one.getManies() );
78+
eeOne = getEntityEntry( s, one );
79+
AbstractPersistentCollection maniesEEOneStateOrig = (AbstractPersistentCollection) eeOne.getLoadedValue( "manies" );
80+
assertNotNull( maniesEEOneStateOrig );
81+
82+
// Ensure maniesEEOneStateOrig has role, key, and session properly defined (even though one.manies == null)
83+
assertEquals( role, maniesEEOneStateOrig.getRole() );
84+
assertEquals( one.getId(), maniesEEOneStateOrig.getKey() );
85+
assertSame( s, maniesEEOneStateOrig.getSession() );
86+
87+
// Ensure there is a CollectionEntry for maniesEEOneStateOrig and that the role, persister, and key are set properly.
88+
CollectionEntry ceManiesOrig = getCollectionEntry( s, maniesEEOneStateOrig );
89+
assertNotNull( ceManiesOrig );
90+
assertEquals( role, ceManiesOrig.getRole() );
91+
assertSame( sessionFactory().getCollectionPersister( role ), ceManiesOrig.getLoadedPersister() );
92+
assertEquals( one.getId(), ceManiesOrig.getKey() );
93+
94+
s.flush();
95+
96+
// Ensure the same EntityEntry is being used.
97+
assertSame( eeOne, getEntityEntry( s, one ) );
98+
99+
// Ensure one.getManies() is still null.
100+
assertNull( one.getManies() );
101+
102+
// Ensure CollectionEntry for maniesEEOneStateOrig is no longer in the PersistenceContext.
103+
assertNull( getCollectionEntry( s, maniesEEOneStateOrig ) );
104+
105+
// Ensure the original CollectionEntry has role, persister, and key set to null.
106+
assertNull( ceManiesOrig.getRole() );
107+
assertNull( ceManiesOrig.getLoadedPersister() );
108+
assertNull( ceManiesOrig.getKey() );
109+
110+
// Ensure the PersistentCollection (that was previously returned by eeOne.getLoadedState())
111+
// has key and role set to null.
112+
assertNull( maniesEEOneStateOrig.getKey() );
113+
assertNull( maniesEEOneStateOrig.getRole() );
114+
115+
// Ensure eeOne.getLoadedState() returns null for collection after flush.
116+
assertNull( eeOne.getLoadedValue( "manies" ) );
117+
118+
// Ensure the session in maniesEEOneStateOrig has been unset.
119+
assertNull( maniesEEOneStateOrig.getSession() );
120+
121+
s.getTransaction().commit();
122+
s.close();
123+
}
124+
125+
@Test
126+
@FailureExpected( jiraKey = "HHH-9777")
127+
public void testGetAndNullifyCollection() {
128+
Session s = openSession();
129+
s.getTransaction().begin();
130+
One one = createOwner();
131+
assertNull( one.getManies() );
132+
s.save( one );
133+
assertNull( one.getManies() );
134+
EntityEntry eeOne = getEntityEntry( s, one );
135+
assertNull( eeOne.getLoadedValue( "manies" ) );
136+
s.flush();
137+
assertNull( one.getManies() );
138+
assertNull( eeOne.getLoadedValue( "manies" ) );
139+
s.getTransaction().commit();
140+
s.close();
141+
142+
final String role = getCollectionOwnerClass().getName() + ".manies";
143+
144+
s = openSession();
145+
s.getTransaction().begin();
146+
one = (One) s.get( getCollectionOwnerClass(), one.getId() );
147+
148+
// When returned by Session.get(), one.getManies() will return a PersistentCollection;
149+
// the EntityEntry loaded state should contain the same PersistentCollection.
150+
151+
eeOne = getEntityEntry( s, one );
152+
assertNotNull( one.getManies() );
153+
AbstractPersistentCollection maniesEEOneStateOrig = (AbstractPersistentCollection) eeOne.getLoadedValue( "manies" );
154+
assertSame( one.getManies(), maniesEEOneStateOrig );
155+
156+
// Ensure maniesEEOneStateOrig has role, key, and session properly defined (even though one.manies == null)
157+
assertEquals( role, maniesEEOneStateOrig.getRole() );
158+
assertEquals( one.getId(), maniesEEOneStateOrig.getKey() );
159+
assertSame( s, maniesEEOneStateOrig.getSession() );
160+
161+
// Ensure there is a CollectionEntry for maniesEEOneStateOrig and that the role, persister, and key are set properly.
162+
CollectionEntry ceManies = getCollectionEntry( s, maniesEEOneStateOrig );
163+
assertNotNull( ceManies );
164+
assertEquals( role, ceManies.getRole() );
165+
assertSame( sessionFactory().getCollectionPersister( role ), ceManies.getLoadedPersister() );
166+
assertEquals( one.getId(), ceManies.getKey() );
167+
168+
// nullify collection
169+
one.setManies( null );
170+
171+
s.flush();
172+
173+
// Ensure the same EntityEntry is being used.
174+
assertSame( eeOne, getEntityEntry( s, one ) );
175+
176+
// Ensure one.getManies() is still null.
177+
assertNull( one.getManies() );
178+
179+
// Ensure CollectionEntry for maniesEEOneStateOrig is no longer in the PersistenceContext.
180+
assertNull( getCollectionEntry( s, maniesEEOneStateOrig ) );
181+
182+
// Ensure the original CollectionEntry has role, persister, and key set to null.
183+
assertNull( ceManies.getRole() );
184+
assertNull( ceManies.getLoadedPersister() );
185+
assertNull( ceManies.getKey() );
186+
187+
// Ensure the PersistentCollection (that was previously returned by eeOne.getLoadedState())
188+
// has key and role set to null.
189+
assertNull( maniesEEOneStateOrig.getKey() );
190+
assertNull( maniesEEOneStateOrig.getRole() );
191+
192+
// Ensure eeOne.getLoadedState() returns null for collection after flush.
193+
assertNull( eeOne.getLoadedValue( "manies" ) );
194+
195+
// Ensure the session in maniesEEOneStateOrig has been unset.
196+
assertNull( maniesEEOneStateOrig.getSession() );
197+
s.getTransaction().commit();
198+
s.close();
199+
}
200+
201+
@Test
202+
@FailureExpected( jiraKey = "HHH-9777")
203+
public void testGetAndReplaceCollection() {
204+
Session s = openSession();
205+
s.getTransaction().begin();
206+
One one = createOwner();
207+
assertNull( one.getManies() );
208+
s.save( one );
209+
assertNull( one.getManies() );
210+
EntityEntry eeOne = getEntityEntry( s, one );
211+
assertNull( eeOne.getLoadedValue( "manies" ) );
212+
s.flush();
213+
assertNull( one.getManies() );
214+
assertNull( eeOne.getLoadedValue( "manies" ) );
215+
s.getTransaction().commit();
216+
s.close();
217+
218+
final String role = getCollectionOwnerClass().getName() + ".manies";
219+
220+
s = openSession();
221+
s.getTransaction().begin();
222+
one = (One) s.get( getCollectionOwnerClass(), one.getId() );
223+
224+
// When returned by Session.get(), one.getManies() will return a PersistentCollection;
225+
// the EntityEntry loaded state should contain the same PersistentCollection.
226+
227+
eeOne = getEntityEntry( s, one );
228+
assertNotNull( one.getManies() );
229+
AbstractPersistentCollection maniesEEOneStateOrig = (AbstractPersistentCollection) eeOne.getLoadedValue( "manies" );
230+
assertSame( one.getManies(), maniesEEOneStateOrig );
231+
232+
// Ensure maniesEEOneStateOrig has role, key, and session properly defined (even though one.manies == null)
233+
assertEquals( role, maniesEEOneStateOrig.getRole() );
234+
assertEquals( one.getId(), maniesEEOneStateOrig.getKey() );
235+
assertSame( s, maniesEEOneStateOrig.getSession() );
236+
237+
// Ensure there is a CollectionEntry for maniesEEOneStateOrig and that the role, persister, and key are set properly.
238+
CollectionEntry ceManiesOrig = getCollectionEntry( s, maniesEEOneStateOrig );
239+
assertNotNull( ceManiesOrig );
240+
assertEquals( role, ceManiesOrig.getRole() );
241+
assertSame( sessionFactory().getCollectionPersister( role ), ceManiesOrig.getLoadedPersister() );
242+
assertEquals( one.getId(), ceManiesOrig.getKey() );
243+
244+
// replace collection
245+
one.setManies( new HashSet<Many>() );
246+
247+
s.flush();
248+
249+
// Ensure the same EntityEntry is being used.
250+
assertSame( eeOne, getEntityEntry( s, one ) );
251+
252+
// Ensure CollectionEntry for maniesEEOneStateOrig is no longer in the PersistenceContext.
253+
assertNull( getCollectionEntry( s, maniesEEOneStateOrig ) );
254+
255+
// Ensure the original CollectionEntry has role, persister, and key set to null.
256+
assertNull( ceManiesOrig.getRole() );
257+
assertNull( ceManiesOrig.getLoadedPersister() );
258+
assertNull( ceManiesOrig.getKey() );
259+
260+
// Ensure the PersistentCollection (that was previously returned by eeOne.getLoadedState())
261+
// has key and role set to null.
262+
assertNull( maniesEEOneStateOrig.getKey() );
263+
assertNull( maniesEEOneStateOrig.getRole() );
264+
265+
// one.getManies() should be "wrapped" by a PersistentCollection now; role, key, and session should be set properly.
266+
assertTrue( PersistentCollection.class.isInstance( one.getManies() ) );
267+
assertEquals( role, ( (PersistentCollection) one.getManies() ).getRole() );
268+
assertEquals( one.getId(), ( (PersistentCollection) one.getManies() ).getKey() );
269+
assertSame( s, ( (AbstractPersistentCollection) one.getManies() ).getSession() );
270+
271+
// Ensure eeOne.getLoadedState() contains the new collection.
272+
assertSame( one.getManies(), eeOne.getLoadedValue( "manies" ) );
273+
274+
// Ensure there is a new CollectionEntry for the new collection and that role, persister, and key are set properly.
275+
CollectionEntry ceManiesAfterReplace = getCollectionEntry( s, (PersistentCollection) one.getManies() );
276+
assertNotNull( ceManiesAfterReplace );
277+
assertEquals( role, ceManiesAfterReplace.getRole() );
278+
assertSame( sessionFactory().getCollectionPersister( role ), ceManiesAfterReplace.getLoadedPersister() );
279+
assertEquals( one.getId(), ceManiesAfterReplace.getKey() );
280+
281+
// Ensure the session in maniesEEOneStateOrig has been unset.
282+
assertNull( maniesEEOneStateOrig.getSession() );
283+
284+
s.getTransaction().commit();
285+
s.close();
286+
}
287+
288+
@Test
289+
public void testSaveOrUpdateNullCollection() {
290+
Session s = openSession();
291+
s.getTransaction().begin();
292+
One one = createOwner();
293+
assertNull( one.getManies() );
294+
s.save( one );
295+
assertNull( one.getManies() );
296+
EntityEntry eeOne = getEntityEntry( s, one );
297+
assertNull( eeOne.getLoadedValue( "manies" ) );
298+
s.flush();
299+
assertNull( one.getManies() );
300+
assertNull( eeOne.getLoadedValue( "manies" ) );
301+
s.getTransaction().commit();
302+
s.close();
303+
304+
final String role = getCollectionOwnerClass().getName() + ".manies";
305+
306+
s = openSession();
307+
s.getTransaction().begin();
308+
s.saveOrUpdate( one );
309+
310+
// Ensure one.getManies() is still null.
311+
assertNull( one.getManies() );
312+
313+
// Ensure the EntityEntry loaded state contains null for the manies collection.
314+
eeOne = getEntityEntry( s, one );
315+
assertNull( eeOne.getLoadedValue( "manies" ) );
316+
317+
s.flush();
318+
319+
// Ensure one.getManies() is still null.
320+
assertNull( one.getManies() );
321+
322+
// Ensure the same EntityEntry is being used.
323+
assertSame( eeOne, getEntityEntry( s, one ) );
324+
325+
// Ensure the EntityEntry loaded state still contains null for the manies collection.
326+
assertNull( eeOne.getLoadedValue( "manies" ) );
327+
328+
s.getTransaction().commit();
329+
s.close();
330+
}
331+
332+
protected abstract Class<?> getCollectionOwnerClass();
333+
334+
protected final One createOwner() {
335+
try {
336+
return (One) getCollectionOwnerClass().newInstance();
337+
}
338+
catch (InstantiationException ex) {
339+
throw new RuntimeException( ex );
340+
}
341+
catch (IllegalAccessException ex) {
342+
throw new RuntimeException( ex );
343+
}
344+
}
345+
346+
private EntityEntry getEntityEntry(Session s, Object entity) {
347+
return ( (SessionImplementor) s ).getPersistenceContext().getEntry( entity );
348+
}
349+
350+
private CollectionEntry getCollectionEntry(Session s, PersistentCollection collection) {
351+
return ( (SessionImplementor) s ).getPersistenceContext().getCollectionEntry( collection );
352+
}
353+
354+
@Override
355+
protected Class[] getAnnotatedClasses() {
356+
return new Class[] {
357+
getCollectionOwnerClass(),
358+
Many.class
359+
};
360+
}
361+
}

0 commit comments

Comments
 (0)