3
* Hibernate, Relational Persistence for Idiomatic Java
5
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
6
* indicated by the @author tags or express copyright attribution
7
* statements applied by the authors. All third-party contributions are
8
* distributed under license by Red Hat Middleware LLC.
10
* This copyrighted material is made available to anyone wishing to use, modify,
11
* copy, or redistribute it subject to the terms and conditions of the GNU
12
* Lesser General Public License, as published by the Free Software Foundation.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
19
* You should have received a copy of the GNU Lesser General Public License
20
* along with this distribution; if not, write to:
21
* Free Software Foundation, Inc.
22
* 51 Franklin Street, Fifth Floor
23
* Boston, MA 02110-1301 USA
27
package org.hibernate.test.cascade;
29
import junit.framework.Test;
31
import org.hibernate.Session;
32
import org.hibernate.TransientObjectException;
33
import org.hibernate.junit.functional.FunctionalTestCase;
34
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
35
import org.hibernate.proxy.HibernateProxy;
38
* @author <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
43
public class MultiPathCascadeTest extends FunctionalTestCase {
45
public MultiPathCascadeTest(String name) {
49
public String[] getMappings() {
51
"cascade/MultiPathCascade.hbm.xml"
55
public static Test suite() {
56
return new FunctionalTestClassTestSuite( MultiPathCascadeTest.class );
59
protected void cleanupTest() {
60
Session s = openSession();
62
s.createQuery( "delete from A" );
63
s.createQuery( "delete from G" );
64
s.createQuery( "delete from H" );
67
public void testMultiPathMergeModifiedDetached() throws Exception
69
// persist a simple A in the database
71
Session s = openSession();
76
s.getTransaction().commit();
79
// modify detached entity
84
a = ( A ) s.merge( a );
85
s.getTransaction().commit();
88
verifyModifications( a.getId() );
91
public void testMultiPathMergeModifiedDetachedIntoProxy() throws Exception
93
// persist a simple A in the database
95
Session s = openSession();
100
s.getTransaction().commit();
103
// modify detached entity
107
s.beginTransaction();
108
A aLoaded = ( A ) s.load( A.class, new Long( a.getId() ) );
109
assertTrue( aLoaded instanceof HibernateProxy );
110
assertSame( aLoaded, s.merge( a ) );
111
s.getTransaction().commit();
114
verifyModifications( a.getId() );
117
public void testMultiPathUpdateModifiedDetached() throws Exception
119
// persist a simple A in the database
121
Session s = openSession();
122
s.beginTransaction();
126
s.getTransaction().commit();
129
// modify detached entity
133
s.beginTransaction();
135
s.getTransaction().commit();
138
verifyModifications( a.getId() );
141
public void testMultiPathGetAndModify() throws Exception
143
// persist a simple A in the database
145
Session s = openSession();
146
s.beginTransaction();
150
s.getTransaction().commit();
154
s.beginTransaction();
155
// retrieve the previously saved instance from the database, and update it
156
a = ( A ) s.get( A.class, new Long( a.getId() ) );
158
s.getTransaction().commit();
161
verifyModifications( a.getId() );
164
public void testMultiPathMergeNonCascadedTransientEntityInCollection() throws Exception
166
// persist a simple A in the database
168
Session s = openSession();
169
s.beginTransaction();
173
s.getTransaction().commit();
176
// modify detached entity
180
s.beginTransaction();
181
a = ( A ) s.merge( a );
182
s.getTransaction().commit();
185
verifyModifications( a.getId() );
187
// add a new (transient) G to collection in h
188
// there is no cascade from H to the collection, so this should fail when merged
189
assertEquals( 1, a.getHs().size() );
190
H h = ( H ) a.getHs().iterator().next();
192
gNew.setData( "Gail" );
193
gNew.getHs().add( h );
194
h.getGs().add( gNew );
197
s.beginTransaction();
201
fail( "should have thrown TransientObjectException" );
203
catch ( TransientObjectException ex ) {
207
s.getTransaction().rollback();
212
public void testMultiPathMergeNonCascadedTransientEntityInOneToOne() throws Exception
214
// persist a simple A in the database
216
Session s = openSession();
217
s.beginTransaction();
221
s.getTransaction().commit();
224
// modify detached entity
228
s.beginTransaction();
229
a = ( A ) s.merge( a );
230
s.getTransaction().commit();
233
verifyModifications( a.getId() );
235
// change the one-to-one association from g to be a new (transient) A
236
// there is no cascade from G to A, so this should fail when merged
240
aNew.setData( "Alice" );
245
s.beginTransaction();
249
fail( "should have thrown TransientObjectException" );
251
catch ( TransientObjectException ex ) {
255
s.getTransaction().rollback();
260
public void testMultiPathMergeNonCascadedTransientEntityInManyToOne() throws Exception
262
// persist a simple A in the database
264
Session s = openSession();
265
s.beginTransaction();
269
s.getTransaction().commit();
272
// modify detached entity
276
s.beginTransaction();
277
a = ( A ) s.merge( a );
278
s.getTransaction().commit();
281
verifyModifications( a.getId() );
283
// change the many-to-one association from h to be a new (transient) A
284
// there is no cascade from H to A, so this should fail when merged
285
assertEquals( 1, a.getHs().size() );
286
H h = ( H ) a.getHs().iterator().next();
287
a.getHs().remove( h );
289
aNew.setData( "Alice" );
293
s.beginTransaction();
297
fail( "should have thrown TransientObjectException" );
299
catch ( TransientObjectException ex ) {
303
s.getTransaction().rollback();
308
private void modifyEntity(A a) {
309
// create a *circular* graph in detached entity
310
a.setData("Anthony");
313
g.setData( "Giovanni" );
316
h.setData( "Hellen" );
328
private void verifyModifications(long aId) {
329
Session s = openSession();
330
s.beginTransaction();
332
// retrieve the A object and check it
333
A a = ( A ) s.get( A.class, new Long( aId ) );
334
assertEquals( aId, a.getId() );
335
assertEquals( "Anthony", a.getData() );
336
assertNotNull( a.getG() );
337
assertNotNull( a.getHs() );
338
assertEquals( 1, a.getHs().size() );
341
H hFromA = ( H ) a.getHs().iterator().next();
343
// check the G object
344
assertEquals( "Giovanni", gFromA.getData() );
345
assertSame( a, gFromA.getA() );
346
assertNotNull( gFromA.getHs() );
347
assertEquals( a.getHs(), gFromA.getHs() );
348
assertSame( hFromA, gFromA.getHs().iterator().next() );
350
// check the H object
351
assertEquals( "Hellen", hFromA.getData() );
352
assertSame( a, hFromA.getA() );
353
assertNotNull( hFromA.getGs() );
354
assertEquals( 1, hFromA.getGs().size() );
355
assertSame( gFromA, hFromA.getGs().iterator().next() );
357
s.getTransaction().commit();