Skip to content

Commit 5eb4c0b

Browse files
committed
HHH-9518 : Add tests for new warnings
1 parent f4f0490 commit 5eb4c0b

File tree

1 file changed

+330
-0
lines changed

1 file changed

+330
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* Copyright (c) 2014, 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.multisession;
25+
26+
import java.util.HashSet;
27+
import java.util.Set;
28+
import javax.persistence.CascadeType;
29+
import javax.persistence.ElementCollection;
30+
import javax.persistence.Entity;
31+
import javax.persistence.GeneratedValue;
32+
import javax.persistence.Id;
33+
import javax.persistence.JoinColumn;
34+
import javax.persistence.OneToMany;
35+
import javax.persistence.Table;
36+
37+
import org.junit.Rule;
38+
import org.junit.Test;
39+
40+
import org.hibernate.Hibernate;
41+
import org.hibernate.HibernateException;
42+
import org.hibernate.Session;
43+
import org.hibernate.collection.internal.AbstractPersistentCollection;
44+
import org.hibernate.collection.spi.PersistentCollection;
45+
import org.hibernate.engine.spi.CollectionEntry;
46+
import org.hibernate.engine.spi.SessionImplementor;
47+
import org.hibernate.internal.CoreLogging;
48+
import org.hibernate.internal.CoreMessageLogger;
49+
import org.hibernate.testing.TestForIssue;
50+
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
51+
import org.hibernate.testing.logger.LoggerInspectionRule;
52+
import org.hibernate.testing.logger.Triggerable;
53+
54+
import static org.junit.Assert.assertFalse;
55+
import static org.junit.Assert.assertNotNull;
56+
import static org.junit.Assert.assertSame;
57+
import static org.junit.Assert.assertTrue;
58+
59+
/**
60+
* @author Gail Badner
61+
*/
62+
public class MultipleSessionCollectionWarningTest extends BaseCoreFunctionalTestCase {
63+
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractPersistentCollection.class );
64+
65+
@Rule
66+
public LoggerInspectionRule logInspection = new LoggerInspectionRule( LOG );
67+
68+
@Test
69+
@TestForIssue( jiraKey = "HHH-9518" )
70+
public void testSetCurrentSessionOverwritesNonConnectedSesssion() {
71+
Parent p = new Parent();
72+
Child c = new Child();
73+
p.children.add( c );
74+
75+
Session s1 = openSession();
76+
s1.getTransaction().begin();
77+
s1.saveOrUpdate( p );
78+
79+
// Now remove the collection from the PersistenceContext without unsetting its session
80+
// This should never be done in practice; it is done here only to test that the warning
81+
// gets logged. s1 will not function properly so the transaction will ultimately need
82+
// to be rolled-back.
83+
84+
CollectionEntry ce = (CollectionEntry) ( (SessionImplementor) s1 ).getPersistenceContext()
85+
.getCollectionEntries()
86+
.remove( p.children );
87+
assertNotNull( ce );
88+
89+
// the collection session should still be s1; the collection is no longer "connected" because its
90+
// CollectionEntry has been removed.
91+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
92+
93+
Session s2 = openSession();
94+
s2.getTransaction().begin();
95+
96+
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000470:" );
97+
assertFalse( triggerable.wasTriggered() );
98+
99+
// The following should trigger warning because we're setting a new session when the collection already
100+
// has a non-null session (and the collection is not "connected" to that session);
101+
// Since s1 was not flushed, the collection role will not be known (no way to test that other than inspection).
102+
s2.saveOrUpdate( p );
103+
104+
assertTrue( triggerable.wasTriggered() );
105+
106+
// collection's session should be overwritten with s2
107+
assertSame( s2, ( (AbstractPersistentCollection) p.children ).getSession() );
108+
109+
s2.getTransaction().rollback();
110+
s2.close();
111+
112+
s1.getTransaction().rollback();
113+
s1.close();
114+
}
115+
116+
@Test
117+
@TestForIssue( jiraKey = "HHH-9518" )
118+
public void testSetCurrentSessionOverwritesNonConnectedSesssionFlushed() {
119+
Parent p = new Parent();
120+
Child c = new Child();
121+
p.children.add( c );
122+
123+
Session s1 = openSession();
124+
s1.getTransaction().begin();
125+
s1.saveOrUpdate( p );
126+
127+
// flush the session so that p.children will contain its role
128+
s1.flush();
129+
130+
// Now remove the collection from the PersistenceContext without unsetting its session
131+
// This should never be done in practice; it is done here only to test that the warning
132+
// gets logged. s1 will not function properly so the transaction will ultimately need
133+
// to be rolled-back.
134+
135+
CollectionEntry ce = (CollectionEntry) ( (SessionImplementor) s1 ).getPersistenceContext()
136+
.getCollectionEntries()
137+
.remove( p.children );
138+
assertNotNull( ce );
139+
140+
// the collection session should still be s1; the collection is no longer "connected" because its
141+
// CollectionEntry has been removed.
142+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
143+
144+
Session s2 = openSession();
145+
s2.getTransaction().begin();
146+
147+
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000470:" );
148+
assertFalse( triggerable.wasTriggered() );
149+
150+
// The following should trigger warning because we're setting a new session when the collection already
151+
// has a non-null session (and the collection is not "connected" to that session);
152+
// The collection role and key should be included in the message (no way to test that other than inspection).
153+
s2.saveOrUpdate( p );
154+
155+
assertTrue( triggerable.wasTriggered() );
156+
157+
// collection's session should be overwritten with s2
158+
assertSame( s2, ( (AbstractPersistentCollection) p.children ).getSession() );
159+
160+
s2.getTransaction().rollback();
161+
s2.close();
162+
163+
s1.getTransaction().rollback();
164+
s1.close();
165+
}
166+
167+
@Test
168+
@TestForIssue( jiraKey = "HHH-9518" )
169+
public void testUnsetSessionCannotOverwriteNonConnectedSesssion() {
170+
Parent p = new Parent();
171+
Child c = new Child();
172+
p.children.add( c );
173+
174+
Session s1 = openSession();
175+
s1.getTransaction().begin();
176+
s1.saveOrUpdate( p );
177+
178+
// Now remove the collection from the PersistenceContext without unsetting its session
179+
// This should never be done in practice; it is done here only to test that the warning
180+
// gets logged. s1 will not function properly so the transaction will ultimately need
181+
// to be rolled-back.
182+
183+
CollectionEntry ce = (CollectionEntry) ( (SessionImplementor) s1 ).getPersistenceContext()
184+
.getCollectionEntries()
185+
.remove( p.children );
186+
assertNotNull( ce );
187+
188+
// the collection session should still be s1; the collection is no longer "connected" because its
189+
// CollectionEntry has been removed.
190+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
191+
192+
Session s2 = openSession();
193+
s2.getTransaction().begin();
194+
195+
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
196+
assertFalse( triggerable.wasTriggered() );
197+
198+
// The following should trigger warning because we're unsetting a different session.
199+
// We should not do this in practice; it is done here only to force the warning.
200+
// Since s1 was not flushed, the collection role will not be known (no way to test that).
201+
assertFalse( ( (PersistentCollection) p.children ).unsetSession( (SessionImplementor) s2 ) );
202+
203+
assertTrue( triggerable.wasTriggered() );
204+
205+
// collection's session should still be s1
206+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
207+
208+
s2.getTransaction().rollback();
209+
s2.close();
210+
211+
s1.getTransaction().rollback();
212+
s1.close();
213+
}
214+
215+
@Test
216+
@TestForIssue( jiraKey = "HHH-9518" )
217+
public void testUnsetSessionCannotOverwriteConnectedSesssion() {
218+
Parent p = new Parent();
219+
Child c = new Child();
220+
p.children.add( c );
221+
222+
Session s1 = openSession();
223+
s1.getTransaction().begin();
224+
s1.saveOrUpdate( p );
225+
226+
// The collection is "connected" to s1 because it contains the CollectionEntry
227+
CollectionEntry ce = ( (SessionImplementor) s1 ).getPersistenceContext()
228+
.getCollectionEntry( (PersistentCollection) p.children );
229+
assertNotNull( ce );
230+
231+
// the collection session should be s1
232+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
233+
234+
Session s2 = openSession();
235+
s2.getTransaction().begin();
236+
237+
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
238+
assertFalse( triggerable.wasTriggered() );
239+
240+
// The following should trigger warning because we're unsetting a different session
241+
// We should not do this in practice; it is done here only to force the warning.
242+
// Since s1 was not flushed, the collection role will not be known (no way to test that).
243+
assertFalse( ( (PersistentCollection) p.children ).unsetSession( (SessionImplementor) s2 ) );
244+
245+
assertTrue( triggerable.wasTriggered() );
246+
247+
// collection's session should still be s1
248+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
249+
250+
s2.getTransaction().rollback();
251+
s2.close();
252+
253+
s1.getTransaction().rollback();
254+
s1.close();
255+
}
256+
257+
@Test
258+
@TestForIssue( jiraKey = "HHH-9518" )
259+
public void testUnsetSessionCannotOverwriteConnectedSesssionFlushed() {
260+
Parent p = new Parent();
261+
Child c = new Child();
262+
p.children.add( c );
263+
264+
Session s1 = openSession();
265+
s1.getTransaction().begin();
266+
s1.saveOrUpdate( p );
267+
268+
// flush the session so that p.children will contain its role
269+
s1.flush();
270+
271+
// The collection is "connected" to s1 because it contains the CollectionEntry
272+
CollectionEntry ce = ( (SessionImplementor) s1 ).getPersistenceContext()
273+
.getCollectionEntry( (PersistentCollection) p.children );
274+
assertNotNull( ce );
275+
276+
// the collection session should be s1
277+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
278+
279+
Session s2 = openSession();
280+
s2.getTransaction().begin();
281+
282+
Triggerable triggerable = logInspection.watchForLogMessages( "HHH000471:" );
283+
assertFalse( triggerable.wasTriggered() );
284+
285+
// The following should trigger warning because we're unsetting a different session
286+
// We should not do this in practice; it is done here only to force the warning.
287+
// The collection role and key should be included in the message (no way to test that other than inspection).
288+
assertFalse( ( (PersistentCollection) p.children ).unsetSession( (SessionImplementor) s2 ) );
289+
290+
assertTrue( triggerable.wasTriggered() );
291+
292+
// collection's session should still be s1
293+
assertSame( s1, ( (AbstractPersistentCollection) p.children ).getSession() );
294+
295+
s2.getTransaction().rollback();
296+
s2.close();
297+
298+
s1.getTransaction().rollback();
299+
s1.close();
300+
}
301+
302+
@Override
303+
public Class<?>[] getAnnotatedClasses() {
304+
return new Class[] {
305+
Parent.class,
306+
Child.class
307+
};
308+
}
309+
310+
@Entity
311+
@Table(name="Parent")
312+
public static class Parent {
313+
@Id
314+
@GeneratedValue
315+
private Long id;
316+
317+
@OneToMany(cascade = CascadeType.ALL)
318+
@JoinColumn
319+
private Set<Child> children = new HashSet<Child>();
320+
}
321+
322+
@Entity
323+
@Table(name="Child")
324+
public static class Child {
325+
@Id
326+
@GeneratedValue
327+
private Long id;
328+
329+
}
330+
}

0 commit comments

Comments
 (0)