KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > odmg > CircularTest


1 package org.apache.ojb.odmg;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22
23 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
24 import org.apache.ojb.broker.metadata.ClassDescriptor;
25 import org.apache.ojb.junit.ODMGTestCase;
26 import org.odmg.OQLQuery;
27 import org.odmg.Transaction;
28
29 /**
30  * Testing complex object graphs with circular and bidirectional references when
31  * using database foreign key settings (without support of deferred foreign keys).
32  * <p/>
33  * The classes hierarchy looks like:
34  * <br/>
35  * Class Shop has a bidirectional 1:1 reference with ShopDetail.<br/>
36  * Shop has a 1:n relation with Product, Product has a 1:1 reference to Shop.<br/>
37  * Shop has a m:n relation with Distributor.<br/>
38  * Product has a 1:n relation to itself to handle sub-Products.<br/>
39  * <p/>
40  * In the database the following foreign keys are declared:
41  * <br/>
42  * - Shop has a FK to ShopDetail<br/>
43  * - Product has a FK to Product<br/>
44  * - Product has a FK to Shop<br/>
45  * - CT_SHOP_DISTRIBUTOR indirection table has FK's to Shop and Distributor<br/>
46  * <p/>
47  * Here a summery of the dependencies:<br/>
48  * Shop--1:1-->ShopDetail--1:1-->Shop<br/>
49  * Shop--1:n-->Product--1:1-->Shop<br/>
50  * Product--1:n-->Product<br/>
51  * Shop--m:n-->Distributor<br/>
52  * <p/>
53  * <p/>
54  * Class ObjectA has a 1:1 reference to ObjectAA,<br/>
55  * ObjectAA has 1:1 to ObjectAAA,<br/>
56  * ObjectAAA has 1:1 to ObjectA and to ObjectAAAA,<br/>
57  * ObjectAAAA has 1:1 to ObjectA<br/>
58  * <br/>
59  * - ObjectA has FK to ObjectAA<br/>
60  * - ObjectAA has FK to ObjectAAA<br/>
61  * - ObjectAAA has FK to ObjectAAAA<br/>
62  * <p/>
63  * Here a summery of the dependencies:<br/>
64  * ObjetA--1:1-->ObjectAA--1:1-->ObjectAAA--1:1-->ObjectA
65  * ObjetA--1:1-->ObjectAA--1:1-->ObjectAAA--1:1-->ObjectAAAA--1:1-->ObjectA
66  *
67  * @version $Id: CircularTest.java,v 1.1.2.10 2005/12/21 22:31:28 tomdz Exp $
68  */

69 public class CircularTest extends ODMGTestCase
70 {
71     public static void main(String JavaDoc[] args)
72     {
73         String JavaDoc[] arr = {CircularTest.class.getName()};
74         junit.textui.TestRunner.main(arr);
75     }
76
77     /**
78      * Handling circular 1:n references with FK settings and use of
79      * auto-delete setting to delete object graph.
80      */

81     public void testCircularOneToN_1() throws Exception JavaDoc
82     {
83         String JavaDoc name = "testCircularOneToN_1_" + System.currentTimeMillis();
84         ojbChangeReferenceSetting(Product.class, "subProducts", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
85
86         Product p1 = new Product(name + "_p1");
87         Product p2 = new Product(name + "_p2");
88         Product p3 = new Product(name + "_p3");
89
90         TransactionExt tx = (TransactionExt) odmg.newTransaction();
91         tx.begin();
92         p1.addSubProduct(p2);
93         p2.addSubProduct(p3);
94         database.makePersistent(p3);
95         // before establishing the circular references write
96
// all objects to DB
97
tx.flush();
98         // now close the circular references
99
p3.addSubProduct(p1);
100         tx.commit();
101
102         tx.begin();
103         // on delete break the circular references first, then delete the
104
// start object
105
tx.lock(p3, Transaction.WRITE);
106         // this call is only needed if auto-delete setting in repository is 'object'
107
tx.setCascadingDelete(Product.class, "subProducts", false);
108         p3.setSubProducts(null);
109         tx.flush();
110         database.deletePersistent(p3);
111         database.deletePersistent(p2);
112         database.deletePersistent(p1);
113         tx.commit();
114
115         tx.begin();
116         OQLQuery query = odmg.newOQLQuery();
117         query.create("select objects from " + Product.class.getName() + " where name like $1");
118         query.bind(name + "%");
119         Collection JavaDoc result = (Collection JavaDoc) query.execute();
120         tx.commit();
121
122         assertEquals(0, result.size());
123     }
124
125     /**
126      * Handling circular 1:n references with FK settings and use of
127      * auto-delete setting to delete object graph.
128      */

129     public void testCircularOneToN_2() throws Exception JavaDoc
130     {
131         String JavaDoc name = "testCircularOneToN_2_" + System.currentTimeMillis();
132         ojbChangeReferenceSetting(Product.class, "subProducts", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
133
134         Product p1 = new Product(name + "_p1");
135         Product p2 = new Product(name + "_p2");
136         Product p3 = new Product(name + "_p3");
137         Product p4 = new Product(name + "_p4");
138         Product p5 = new Product(name + "_p5");
139         Product p6 = new Product(name + "_p6");
140         Product p7 = new Product(name + "_p7");
141
142         TransactionExt tx = (TransactionExt) odmg.newTransaction();
143         tx.begin();
144         p1.addSubProduct(p2);
145         p1.addSubProduct(p3);
146         p3.addSubProduct(p4);
147         p3.addSubProduct(p5);
148         p5.addSubProduct(p6);
149         p6.addSubProduct(p7);
150         database.makePersistent(p1);
151         // before establishing the circular references write
152
// all objects to DB
153
tx.flush();
154         // now close the circular references
155
p6.addSubProduct(p1);
156         tx.commit();
157
158         tx.begin();
159         // on delete break the circular references first, then delete the
160
// start object
161
tx.lock(p6, Transaction.WRITE);
162         tx.setCascadingDelete(Product.class, "subProducts", false);
163         p6.setSubProducts(null);
164         tx.flush();
165         tx.setCascadingDelete(Product.class, "subProducts", true);
166         database.deletePersistent(p1);
167         tx.commit();
168
169         tx.begin();
170         OQLQuery query = odmg.newOQLQuery();
171         query.create("select objects from " + Product.class.getName() + " where name like $1");
172         query.bind(name + "%");
173         Collection JavaDoc result = (Collection JavaDoc) query.execute();
174         tx.commit();
175
176         // we expect one Product object, because we set cascading delete 'false'
177
// when do 'p6.setSubProducts(null);', so the '..._p7' Product will only be unlinked
178
assertEquals(1, result.size());
179         Product p7_new = (Product) result.iterator().next();
180         assertEquals(name + "_p7", p7_new.getName());
181     }
182
183     /**
184      * Handling circular 1:n references with FK settings and use of
185      * auto-delete setting to delete object graph.
186      */

187     public void testCircularOneToN_3() throws Exception JavaDoc
188     {
189         String JavaDoc name = "testCircularOneToN_3_" + System.currentTimeMillis();
190         ojbChangeReferenceSetting(Product.class, "subProducts", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
191
192         Product p1 = new Product(name + "_p1");
193         Product p2 = new Product(name + "_p2");
194         Product p3 = new Product(name + "_p3");
195
196         TransactionExt tx = (TransactionExt) odmg.newTransaction();
197         tx.begin();
198         p1.addSubProduct(p2);
199         p2.addSubProduct(p3);
200         database.makePersistent(p3);
201         // before establishing the circular references write
202
// all objects to DB
203
tx.flush();
204         // now close the circular references
205
p3.addSubProduct(p1);
206         tx.commit();
207
208         tx.begin();
209         // on delete break the circular references first, then delete the
210
// start object
211
tx.lock(p3, Transaction.WRITE);
212         // this call is only needed if auto-delete setting in repository is 'object'
213
tx.setCascadingDelete(Product.class, "subProducts", false);
214         p3.setSubProducts(null);
215         tx.flush();
216         // this call is only needed if auto-delete setting in repository is 'none'
217
// to enable cascade delete, else we have to delete each object by hand
218
tx.setCascadingDelete(Product.class, "subProducts", true);
219         database.deletePersistent(p1);
220         tx.commit();
221
222         tx.begin();
223         OQLQuery query = odmg.newOQLQuery();
224         query.create("select objects from " + Product.class.getName() + " where name like $1");
225         query.bind(name + "%");
226         Collection JavaDoc result = (Collection JavaDoc) query.execute();
227         tx.commit();
228
229         assertEquals(0, result.size());
230     }
231
232     /**
233      * Use auto-delete setting to delete object graph.
234      */

235     public void testCircularWithAutoDeleteEnabled() throws Exception JavaDoc
236     {
237         String JavaDoc name = "testCircularWithAutoDeleteEnabled_" + System.currentTimeMillis();
238
239         ojbChangeReferenceSetting(ObjectA.class, "refAA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
240         ojbChangeReferenceSetting(ObjectAA.class, "refAAA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
241         ojbChangeReferenceSetting(ObjectAAA.class, "refAAAA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
242         ojbChangeReferenceSetting(ObjectAAAA.class, "refA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
243
244         ObjectA a = new ObjectA(name + "_ObjectA");
245         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
246         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
247         ObjectAAAA aaaa = new ObjectAAAA(name + "_ObjectAAAA");
248         // now set the circular references
249
a.setRefAA(aa);
250         aa.setRefAAA(aaa);
251         aaa.setRefAAAA(aaaa);
252         aaaa.setRefA(a);
253
254         TransactionExt tx = (TransactionExt) odmg.newTransaction();
255         tx.begin();
256         database.makePersistent(a);
257         tx.commit();
258
259         tx.begin();
260         OQLQuery query = odmg.newOQLQuery();
261         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
262         query.bind(name + "%");
263         Collection JavaDoc result = (Collection JavaDoc) query.execute();
264         assertEquals(1, result.size());
265
266         query = odmg.newOQLQuery();
267         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
268         query.bind(name + "%");
269         result = (Collection JavaDoc) query.execute();
270         assertEquals(1, result.size());
271
272         query = odmg.newOQLQuery();
273         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
274         query.bind(name + "%");
275         result = (Collection JavaDoc) query.execute();
276         assertEquals(1, result.size());
277
278         query = odmg.newOQLQuery();
279         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
280         query.bind(name + "%");
281         result = (Collection JavaDoc) query.execute();
282         assertEquals(1, result.size());
283         tx.commit();
284
285         tx.begin();
286         /*
287         arminw: When deleting a object which is part of circular 1:1 references
288         with cascade delete enabled it's mandatory to break the circular reference
289         before deleting it.
290         */

291         tx.lock(aaaa, Transaction.WRITE);
292         // break the circular references
293
aaaa.setRefA(null);
294         database.deletePersistent(a);
295         tx.commit();
296
297         tx.begin();
298         query = odmg.newOQLQuery();
299         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
300         query.bind(name + "%");
301         result = (Collection JavaDoc) query.execute();
302         assertEquals(0, result.size());
303
304         query = odmg.newOQLQuery();
305         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
306         query.bind(name + "%");
307         result = (Collection JavaDoc) query.execute();
308         assertEquals(0, result.size());
309
310         query = odmg.newOQLQuery();
311         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
312         query.bind(name + "%");
313         result = (Collection JavaDoc) query.execute();
314         assertEquals(0, result.size());
315
316         query = odmg.newOQLQuery();
317         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
318         query.bind(name + "%");
319         result = (Collection JavaDoc) query.execute();
320         assertEquals(0, result.size());
321         tx.commit();
322     }
323
324     /**
325      * Use auto-delete setting to delete object graph.
326      */

327     public void testAutoDeleteEnabledNonCircular() throws Exception JavaDoc
328     {
329         String JavaDoc name = "testAutoDeleteEnabledNonCircular_" + System.currentTimeMillis();
330
331         ojbChangeReferenceSetting(ObjectA.class, "refAA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
332         ojbChangeReferenceSetting(ObjectAA.class, "refAAA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
333         ojbChangeReferenceSetting(ObjectAAA.class, "refAAAA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
334         ojbChangeReferenceSetting(ObjectAAAA.class, "refA", true, ObjectReferenceDescriptor.CASCADE_NONE, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
335
336         ObjectA a = new ObjectA(name + "_ObjectA");
337         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
338         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
339         ObjectAAAA aaaa = new ObjectAAAA(name + "_ObjectAAAA");
340         // now set the references
341
a.setRefAA(aa);
342         aa.setRefAAA(aaa);
343         aaa.setRefAAAA(aaaa);
344
345         TransactionExt tx = (TransactionExt) odmg.newTransaction();
346         tx.begin();
347         database.makePersistent(a);
348         tx.commit();
349
350         tx.begin();
351         OQLQuery query = odmg.newOQLQuery();
352         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
353         query.bind(name + "%");
354         Collection JavaDoc result = (Collection JavaDoc) query.execute();
355         assertEquals(1, result.size());
356
357         query = odmg.newOQLQuery();
358         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
359         query.bind(name + "%");
360         result = (Collection JavaDoc) query.execute();
361         assertEquals(1, result.size());
362
363         query = odmg.newOQLQuery();
364         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
365         query.bind(name + "%");
366         result = (Collection JavaDoc) query.execute();
367         assertEquals(1, result.size());
368
369         query = odmg.newOQLQuery();
370         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
371         query.bind(name + "%");
372         result = (Collection JavaDoc) query.execute();
373         assertEquals(1, result.size());
374         tx.commit();
375
376         tx.begin();
377         database.deletePersistent(a);
378         tx.commit();
379
380         tx.begin();
381         query = odmg.newOQLQuery();
382         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
383         query.bind(name + "%");
384         result = (Collection JavaDoc) query.execute();
385         assertEquals(0, result.size());
386
387         query = odmg.newOQLQuery();
388         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
389         query.bind(name + "%");
390         result = (Collection JavaDoc) query.execute();
391         assertEquals(0, result.size());
392
393         query = odmg.newOQLQuery();
394         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
395         query.bind(name + "%");
396         result = (Collection JavaDoc) query.execute();
397         assertEquals(0, result.size());
398
399         query = odmg.newOQLQuery();
400         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
401         query.bind(name + "%");
402         result = (Collection JavaDoc) query.execute();
403         assertEquals(0, result.size());
404         tx.commit();
405     }
406
407     /**
408      * Handle circuler 1:1 with default methods.
409      */

410     public void testBidirectionalWithConstraint_1a() throws Exception JavaDoc
411     {
412         String JavaDoc name = "testBidirectionalWithConstraint_1a_" + System.currentTimeMillis();
413
414         Shop s1 = new Shop(name + "_1");
415         ShopDetail sd = new ShopDetail(name + "_1");
416         s1.setDetail(sd);
417         sd.setShop(s1);
418
419         TransactionExt tx = (TransactionExt) odmg.newTransaction();
420         tx.begin();
421         database.makePersistent(s1);
422         tx.commit();
423
424         tx.begin();
425         database.deletePersistent(s1);
426         tx.commit();
427     }
428
429     /**
430      * Define order of object operations using flush() method.
431      */

432     public void testBidirectionalWithConstraint_1b() throws Exception JavaDoc
433     {
434         String JavaDoc name = "testBidirectionalWithConstraint_1b_" + System.currentTimeMillis();
435         TransactionExt tx = (TransactionExt) odmg.newTransaction();
436         tx.begin();
437
438         Shop s1 = new Shop(name + "_1");
439         // when using flush() we can use the "natural" order
440
// without getting DB constraint violence.
441
database.makePersistent(s1);
442         // write to DB object without references
443
tx.flush();
444         ShopDetail sd = new ShopDetail(name + "_1");
445         // now set references
446
s1.setDetail(sd);
447         sd.setShop(s1);
448         // no need to persist the ShopDetail object
449
// (will be detected by OJB)
450
// but it doesn't matter if you do
451
// database.makePersistent(sd);
452
tx.commit();
453
454         tx.begin();
455         // madatory to mark object with DB FK constraint first on delete
456
// (FK from Shop to ShopDetail) then OJB will use this order to
457
// delete the bidirectional objects
458
database.deletePersistent(s1);
459         tx.flush();
460         database.deletePersistent(sd);
461         tx.commit();
462     }
463
464     /**
465      * If the user take care of the ordering itself the test pass.
466      */

467     public void testBidirectionalWithConstraint_1c() throws Exception JavaDoc
468     {
469         String JavaDoc name = "testBidirectionalWithConstraint_1c_" + System.currentTimeMillis();
470         TransactionExt tx = (TransactionExt) odmg.newTransaction();
471
472         Shop s1 = new Shop(name + "_1");
473         ShopDetail sd = new ShopDetail(name + "_1");
474         s1.setDetail(sd);
475         sd.setShop(s1);
476
477         // set implicit locking false to determine order of objects
478
tx.setImplicitLocking(false);
479         // to prevent reordering of object, disable ordering
480
// in many cases this is not needed, because OJB will leave ordering
481
// tx.setOrdering(false);
482
tx.begin();
483         // madatory to persist referenced ShopDetail first, the Shop
484
// object will be detected automatic. In this case first the ShopDetail
485
// will be created and then the Shop
486
database.makePersistent(sd);
487         database.makePersistent(s1);
488         tx.commit();
489
490         // we using the same tx, thus locking and (ordering) is still disabled
491
tx.begin();
492         // madatory to mark object with DB FK constraint first on delete
493
// then OJB will use this order to delete the bidirectional objects
494
database.deletePersistent(s1);
495         database.deletePersistent(sd);
496         tx.commit();
497     }
498
499     /**
500      * This test is only for comparison of ODMG- with PB-api. It's not recommended
501      * to do this in ODMG production environment.
502      *
503      * @throws Exception
504      */

505     public void testBidirectionalWithConstraint_1d_PB() throws Exception JavaDoc
506     {
507         ojbChangeReferenceSetting(Shop.class, "detail", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
508         ojbChangeReferenceSetting(ShopDetail.class, "shop", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
509         String JavaDoc name = "testBidirectionalWithConstraint_1a_" + System.currentTimeMillis();
510         TransactionExt tx = (TransactionExt) odmg.newTransaction();
511         tx.begin();
512
513         Shop s1 = new Shop(name + "_1");
514         ShopDetail sd = new ShopDetail(name + "_1");
515         s1.setDetail(sd);
516         sd.setShop(s1);
517
518         // only for testing, we completely bypass odmg
519
tx.getBroker().beginTransaction();
520         tx.getBroker().store(s1);
521         tx.commit();
522
523
524         tx.begin();
525         // only for testing, we completely bypass odmg
526
tx.getBroker().beginTransaction();
527         // madatory to mark object with DB FK constraint first on delete
528
// then OJB will use this order to delete the bidirectional objects
529
tx.getBroker().delete(s1);
530         tx.commit();
531     }
532
533     /**
534      * Handle circular 1:1 by using a 'constraint'-flag property in
535      * reference-descriptor to make OJB's ordering algorithm more
536      * sophisticated.
537      */

538     public void testBidirectionalWithConstraint_1e() throws Exception JavaDoc
539     {
540         String JavaDoc name = "testBidirectionalWithConstraint_1e_" + System.currentTimeMillis();
541         ObjectReferenceDescriptor ord = null;
542
543         try
544         {
545             CircularTest.Shop s1 = new CircularTest.Shop(name + "_1");
546             CircularTest.ShopDetail sd = new CircularTest.ShopDetail(name + "_1");
547             s1.setDetail(sd);
548             sd.setShop(s1);
549
550             TransactionExt tx = (TransactionExt) odmg.newTransaction();
551             tx.begin();
552             // now we tell OJB that one 1:1 reference of the bidirectional 1:1 reference
553
// between Shop and ShopDetail has a FK constraint
554
ClassDescriptor cld = tx.getBroker().getClassDescriptor(CircularTest.Shop.class);
555             ord = cld.getObjectReferenceDescriptorByName("detail");
556             // current DB schema create a foreign key constraint and we can
557
// inform OJB
558
ord.setConstraint(true);
559             // now it doesn't matter in which order we persist the new objects, OJB should
560
// always reorder the objects before insert/update call
561
database.makePersistent(sd);
562             // or
563
// database.makePersistent(s1);
564
tx.commit();
565
566             tx.begin();
567             // with cascading delete and the declared FK constraint OJB
568
// always use the correct order on delete.
569
tx.setCascadingDelete(CircularTest.ShopDetail.class, true);
570             database.deletePersistent(sd);
571             // or
572
// database.deletePersistent(s1);
573
tx.commit();
574         }
575         finally
576         {
577             // restore old setting
578
if(ord != null) ord.setConstraint(false);
579         }
580     }
581
582     /**
583      * Test show handling with circular references and database FK settings.
584      */

585     public void testCircularOneToOne_1a() throws Exception JavaDoc
586     {
587         String JavaDoc name = "testCircularOneToOne_1a_" + System.currentTimeMillis();
588
589         TransactionExt tx = (TransactionExt) odmg.newTransaction();
590         tx.begin();
591
592         ObjectA a = new ObjectA(name + "_ObjectA");
593         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
594         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
595         // now set the circular references
596
a.setRefAA(aa);
597         aa.setRefAAA(aaa);
598         aaa.setRefA(a);
599         database.makePersistent(a);
600         tx.commit();
601
602         tx.begin();
603         database.deletePersistent(a);
604         tx.commit();
605
606         tx.begin();
607         OQLQuery query = odmg.newOQLQuery();
608         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
609         query.bind(name + "%");
610         Collection JavaDoc result = (Collection JavaDoc) query.execute();
611         assertEquals(0, result.size());
612
613         query = odmg.newOQLQuery();
614         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
615         query.bind(name + "%");
616         result = (Collection JavaDoc) query.execute();
617         assertEquals(1, result.size());
618
619         query = odmg.newOQLQuery();
620         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
621         query.bind(name + "%");
622         result = (Collection JavaDoc) query.execute();
623         assertEquals(1, result.size());
624
625         query = odmg.newOQLQuery();
626         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
627         query.bind(name + "%");
628         result = (Collection JavaDoc) query.execute();
629         assertEquals(0, result.size());
630         tx.commit();
631     }
632
633     /**
634      * Test show handling with circular references and database FK settings.
635      */

636     public void testCircularOneToOne_1b() throws Exception JavaDoc
637     {
638         String JavaDoc name = "testCircularOneToOne_1b_" + System.currentTimeMillis();
639
640         TransactionExt tx = (TransactionExt) odmg.newTransaction();
641         tx.begin();
642
643         ObjectA a = new ObjectA(name + "_ObjectA");
644         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
645         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
646         ObjectAAAA aaaa = new ObjectAAAA(name + "_ObjectAAAA");
647         // now set the circular references
648
a.setRefAA(aa);
649         aa.setRefAAA(aaa);
650         aaa.setRefAAAA(aaaa);
651         aaaa.setRefA(a);
652         database.makePersistent(a);
653         tx.commit();
654
655         tx.begin();
656         OQLQuery query = odmg.newOQLQuery();
657         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
658         query.bind(name + "%");
659         Collection JavaDoc result = (Collection JavaDoc) query.execute();
660         assertEquals(1, result.size());
661
662         query = odmg.newOQLQuery();
663         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
664         query.bind(name + "%");
665         result = (Collection JavaDoc) query.execute();
666         assertEquals(1, result.size());
667
668         query = odmg.newOQLQuery();
669         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
670         query.bind(name + "%");
671         result = (Collection JavaDoc) query.execute();
672         assertEquals(1, result.size());
673
674         query = odmg.newOQLQuery();
675         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
676         query.bind(name + "%");
677         result = (Collection JavaDoc) query.execute();
678         assertEquals(1, result.size());
679         tx.commit();
680
681         tx.begin();
682         database.deletePersistent(a);
683         tx.commit();
684
685         tx.begin();
686         query = odmg.newOQLQuery();
687         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
688         query.bind(name + "%");
689         result = (Collection JavaDoc) query.execute();
690         assertEquals(0, result.size());
691
692         query = odmg.newOQLQuery();
693         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
694         query.bind(name + "%");
695         result = (Collection JavaDoc) query.execute();
696         assertEquals(1, result.size());
697
698         query = odmg.newOQLQuery();
699         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
700         query.bind(name + "%");
701         result = (Collection JavaDoc) query.execute();
702         assertEquals(1, result.size());
703
704         query = odmg.newOQLQuery();
705         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
706         query.bind(name + "%");
707         result = (Collection JavaDoc) query.execute();
708         assertEquals(1, result.size());
709         tx.commit();
710     }
711
712     /**
713      * Do manually ordering using {@link TransactionExt#setOrdering(boolean)} to disable
714      * OJB's ordering algorithm (and implicit locking).
715      */

716     public void testCircularOneToOne_1c() throws Exception JavaDoc
717     {
718         String JavaDoc name = "testCircularOneToOne_1d_" + System.currentTimeMillis();
719
720         TransactionExt tx = (TransactionExt) odmg.newTransaction();
721         tx.begin();
722
723         ObjectA a = new ObjectA(name + "_ObjectA");
724         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
725         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
726         ObjectAAAA aaaa = new ObjectAAAA(name + "_ObjectAAAA");
727         // now set the circular references
728
a.setRefAA(aa);
729         aa.setRefAAA(aaa);
730         aaa.setRefAAAA(aaaa);
731         aaaa.setRefA(a);
732
733         /*
734         we want to manually insert new object, so we disable
735         OJB's ordering and implicit object locking
736         */

737         tx.setOrdering(false);
738         tx.setImplicitLocking(false);
739
740         database.makePersistent(aaaa);
741         database.makePersistent(aaa);
742         database.makePersistent(aa);
743         database.makePersistent(a);
744         tx.commit();
745
746         tx.begin();
747         OQLQuery query = odmg.newOQLQuery();
748         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
749         query.bind(name + "%");
750         Collection JavaDoc result = (Collection JavaDoc) query.execute();
751         assertEquals(1, result.size());
752
753         query = odmg.newOQLQuery();
754         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
755         query.bind(name + "%");
756         result = (Collection JavaDoc) query.execute();
757         assertEquals(1, result.size());
758
759         query = odmg.newOQLQuery();
760         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
761         query.bind(name + "%");
762         result = (Collection JavaDoc) query.execute();
763         assertEquals(1, result.size());
764
765         query = odmg.newOQLQuery();
766         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
767         query.bind(name + "%");
768         result = (Collection JavaDoc) query.execute();
769         assertEquals(1, result.size());
770         tx.commit();
771
772         tx.begin();
773         /*
774         the ordering/implicit locking of the tx is still disabled (tx instance hasn't changed),
775         so we have to take care of correct order of objects while deletion
776         */

777         database.deletePersistent(a);
778         database.deletePersistent(aa);
779         database.deletePersistent(aaa);
780         database.deletePersistent(aaaa);
781         tx.commit();
782
783         tx.begin();
784         query = odmg.newOQLQuery();
785         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
786         query.bind(name + "%");
787         result = (Collection JavaDoc) query.execute();
788         assertEquals(0, result.size());
789
790         query = odmg.newOQLQuery();
791         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
792         query.bind(name + "%");
793         result = (Collection JavaDoc) query.execute();
794         assertEquals(0, result.size());
795
796         query = odmg.newOQLQuery();
797         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
798         query.bind(name + "%");
799         result = (Collection JavaDoc) query.execute();
800         assertEquals(0, result.size());
801
802         query = odmg.newOQLQuery();
803         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
804         query.bind(name + "%");
805         result = (Collection JavaDoc) query.execute();
806         assertEquals(0, result.size());
807         tx.commit();
808     }
809
810     /**
811      * Do manually ordering using in conjunction with OJB's ordering.
812      */

813     public void testCircularOneToOne_1dd() throws Exception JavaDoc
814     {
815         String JavaDoc name = "testCircularOneToOne_1dd_" + System.currentTimeMillis();
816
817         TransactionExt tx = (TransactionExt) odmg.newTransaction();
818         tx.begin();
819
820         ObjectA a = new ObjectA(name + "_ObjectA");
821         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
822         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
823         ObjectAAAA aaaa = new ObjectAAAA(name + "_ObjectAAAA");
824         // now set the circular references
825
a.setRefAA(aa);
826         aa.setRefAAA(aaa);
827         aaa.setRefAAAA(aaaa);
828         aaaa.setRefA(a);
829
830         /*
831         we manually determine the insert object order
832         */

833         tx.setOrdering(false);
834         tx.setImplicitLocking(false);
835
836         database.makePersistent(aaaa);
837         database.makePersistent(aaa);
838         database.makePersistent(aa);
839         database.makePersistent(a);
840         tx.commit();
841
842         tx.begin();
843         /*
844         the ordering/implicit locking/noteOrdering settings are still enabled
845         */

846         database.deletePersistent(a);
847         database.deletePersistent(aa);
848         database.deletePersistent(aaa);
849         database.deletePersistent(aaaa);
850         tx.commit();
851
852         tx.begin();
853         OQLQuery query = odmg.newOQLQuery();
854         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
855         query.bind(name + "%");
856         Collection JavaDoc result = (Collection JavaDoc) query.execute();
857         assertEquals(0, result.size());
858
859         query = odmg.newOQLQuery();
860         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
861         query.bind(name + "%");
862         result = (Collection JavaDoc) query.execute();
863         assertEquals(0, result.size());
864
865         query = odmg.newOQLQuery();
866         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
867         query.bind(name + "%");
868         result = (Collection JavaDoc) query.execute();
869         assertEquals(0, result.size());
870
871         query = odmg.newOQLQuery();
872         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
873         query.bind(name + "%");
874         result = (Collection JavaDoc) query.execute();
875         assertEquals(0, result.size());
876         tx.commit();
877     }
878
879     public void testCircularOneToOne_1e() throws Exception JavaDoc
880     {
881         String JavaDoc name = "testCircularOneToOne_1e_" + System.currentTimeMillis();
882
883         TransactionExt tx = (TransactionExt) odmg.newTransaction();
884         tx.begin();
885
886         ObjectA a = new ObjectA(name + "_ObjectA");
887         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
888         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
889         ObjectAAAA aaaa = new ObjectAAAA(name + "_ObjectAAAA");
890         // now set the circular references
891
a.setRefAA(aa);
892         aa.setRefAAA(aaa);
893         aaa.setRefAAAA(aaaa);
894         aaaa.setRefA(a);
895
896         database.makePersistent(a);
897         tx.commit();
898
899         tx.begin();
900         // delete one object from an object graph
901
tx.lock(aa, Transaction.WRITE);
902         aa.setRefAAA(null);
903         database.deletePersistent(aaa);
904         tx.commit();
905
906         tx.begin();
907         OQLQuery query = odmg.newOQLQuery();
908         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
909         query.bind(name + "%");
910         Collection JavaDoc result = (Collection JavaDoc) query.execute();
911         assertEquals(1, result.size());
912
913         query = odmg.newOQLQuery();
914         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
915         query.bind(name + "%");
916         result = (Collection JavaDoc) query.execute();
917         assertEquals(1, result.size());
918
919         query = odmg.newOQLQuery();
920         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
921         query.bind(name + "%");
922         result = (Collection JavaDoc) query.execute();
923         assertEquals(0, result.size());
924
925         query = odmg.newOQLQuery();
926         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
927         query.bind(name + "%");
928         result = (Collection JavaDoc) query.execute();
929         assertEquals(1, result.size());
930         tx.commit();
931     }
932
933     /**
934      * User take care of the ordering itself.
935      */

936     public void testCircularOneToOne_2a() throws Exception JavaDoc
937     {
938         String JavaDoc name = "testCircularOneToOne_2_" + System.currentTimeMillis();
939
940         ObjectA a = new ObjectA(name + "_ObjectA");
941         ObjectAA aa = new ObjectAA(name + "_ObjectAA");
942         ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
943         // now set the circular references
944
a.setRefAA(aa);
945         aa.setRefAAA(aaa);
946         aaa.setRefA(a);
947
948         TransactionExt tx = (TransactionExt) odmg.newTransaction();
949         // we want control object insert order itself, thus
950
// disable implicite locking and ordering
951
tx.setImplicitLocking(false);
952         tx.setOrdering(false);
953         tx.begin();
954         database.makePersistent(aaa);
955         database.makePersistent(aa);
956         database.makePersistent(a);
957         tx.commit();
958
959         // we use the same tx again, thus implicite locking
960
// and ordering is still disabled
961
tx.begin();
962         database.deletePersistent(a);
963         database.deletePersistent(aa);
964         database.deletePersistent(aaa);
965         tx.commit();
966
967         tx.begin();
968         OQLQuery query = odmg.newOQLQuery();
969         query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
970         query.bind(name + "%");
971         Collection JavaDoc result = (Collection JavaDoc) query.execute();
972         assertEquals(0, result.size());
973
974         query = odmg.newOQLQuery();
975         query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
976         query.bind(name + "%");
977         result = (Collection JavaDoc) query.execute();
978         assertEquals(0, result.size());
979
980         query = odmg.newOQLQuery();
981         query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
982         query.bind(name + "%");
983         result = (Collection JavaDoc) query.execute();
984         assertEquals(0, result.size());
985
986         query = odmg.newOQLQuery();
987         query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
988         query.bind(name + "%");
989         result = (Collection JavaDoc) query.execute();
990         assertEquals(0, result.size());
991         tx.commit();
992     }
993
994     /**
995      * This test is only for comparison of ODMG- with PB-api. It's not recommended
996      * to do this in ODMG production environment.
997      * Handling of circular 1:1 reference: ObjetA--1:1-->ObjectAA--1:1-->ObjectAAA--1:1-->ObjectA
998      * when each object has a FK constraint to it's reference.
999      *
1000     * @throws Exception
1001     */

1002    public void testCircularOneToOne_PB_a() throws Exception JavaDoc
1003    {
1004        ojbChangeReferenceSetting(ObjectA.class, "refAA", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
1005        ojbChangeReferenceSetting(ObjectAA.class, "refAAA", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
1006        //ojbChangeReferenceSetting(ObjectAAA.class, "refA", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
1007
String JavaDoc name = "testCircularOneToOne_PB" + System.currentTimeMillis();
1008        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1009        tx.begin();
1010
1011        ObjectA a = new ObjectA(name + "_ObjectA");
1012        // only for testing, we completely bypass odmg
1013
tx.getBroker().beginTransaction();
1014        //tx.getBroker().store(a);
1015

1016        ObjectAA aa = new ObjectAA(name + "_ObjectAA");
1017        ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
1018        // now set the circular references
1019
a.setRefAA(aa);
1020        aa.setRefAAA(aaa);
1021        aaa.setRefA(a);
1022        tx.getBroker().store(a);
1023        tx.commit();
1024
1025        tx.begin();
1026        OQLQuery query = odmg.newOQLQuery();
1027        query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
1028        query.bind(name + "%");
1029        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1030        assertEquals(1, result.size());
1031
1032        query = odmg.newOQLQuery();
1033        query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
1034        query.bind(name + "%");
1035        result = (Collection JavaDoc) query.execute();
1036        assertEquals(1, result.size());
1037
1038        query = odmg.newOQLQuery();
1039        query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
1040        query.bind(name + "%");
1041        result = (Collection JavaDoc) query.execute();
1042        assertEquals(1, result.size());
1043
1044        query = odmg.newOQLQuery();
1045        query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
1046        query.bind(name + "%");
1047        result = (Collection JavaDoc) query.execute();
1048        assertEquals(0, result.size());
1049        tx.commit();
1050
1051
1052        tx.begin();
1053        // only for testing, we completely bypass odmg
1054
tx.getBroker().beginTransaction();
1055        // madatory to mark object with DB FK constraint first on delete
1056
// then OJB will use this order to delete the bidirectional objects
1057
//aaa.setRefA(null);
1058
//tx.getBroker().store(aaa);
1059
tx.getBroker().delete(a);
1060        tx.commit();
1061
1062        tx.begin();
1063        query = odmg.newOQLQuery();
1064        query.create("select objects from " + ObjectA.class.getName() + " where name like $1");
1065        query.bind(name + "%");
1066        result = (Collection JavaDoc) query.execute();
1067        assertEquals(0, result.size());
1068
1069        query = odmg.newOQLQuery();
1070        query.create("select objects from " + ObjectAA.class.getName() + " where name like $1");
1071        query.bind(name + "%");
1072        result = (Collection JavaDoc) query.execute();
1073        assertEquals(0, result.size());
1074
1075        query = odmg.newOQLQuery();
1076        query.create("select objects from " + ObjectAAA.class.getName() + " where name like $1");
1077        query.bind(name + "%");
1078        result = (Collection JavaDoc) query.execute();
1079        assertEquals(0, result.size());
1080
1081        query = odmg.newOQLQuery();
1082        query.create("select objects from " + ObjectAAAA.class.getName() + " where name like $1");
1083        query.bind(name + "%");
1084        result = (Collection JavaDoc) query.execute();
1085        assertEquals(0, result.size());
1086        tx.commit();
1087    }
1088
1089    /**
1090     * This test is only for comparison of ODMG- with PB-api. It's not recommended
1091     * to do this in ODMG production environment.
1092     * Handling of circular 1:1 reference: ObjetA--1:1-->ObjectAA--1:1-->ObjectAAA--1:1-->ObjectA
1093     * when each object has a FK constraint to it's reference.
1094     *
1095     * @throws Exception
1096     */

1097    public void testCircularOneToOne_PB_b() throws Exception JavaDoc
1098    {
1099        ojbChangeReferenceSetting(ObjectA.class, "refAA", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
1100        ojbChangeReferenceSetting(ObjectAA.class, "refAAA", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
1101        //ojbChangeReferenceSetting(ObjectAAA.class, "refA", true, ObjectReferenceDescriptor.CASCADE_OBJECT, ObjectReferenceDescriptor.CASCADE_OBJECT, false);
1102
String JavaDoc name = "testCircularOneToOne_PB" + System.currentTimeMillis();
1103        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1104        tx.begin();
1105
1106        // only for testing, we completely bypass odmg
1107
tx.getBroker().beginTransaction();
1108        //tx.getBroker().store(a);
1109

1110        ObjectA a = new ObjectA(name + "_ObjectA");
1111        ObjectAA aa = new ObjectAA(name + "_ObjectAA");
1112        ObjectAAA aaa = new ObjectAAA(name + "_ObjectAAA");
1113        ObjectAAAA aaaa = new ObjectAAAA(name + "_ObjectAAAA");
1114        // now set the circular references
1115
a.setRefAA(aa);
1116        aa.setRefAAA(aaa);
1117        aaa.setRefAAAA(aaaa);
1118        aaaa.setRefA(a);
1119
1120        tx.getBroker().store(a);
1121
1122        tx.commit();
1123
1124
1125        tx.begin();
1126        // only for testing, we completely bypass odmg
1127
tx.getBroker().beginTransaction();
1128        // madatory to mark object with DB FK constraint first on delete
1129
// then OJB will use this order to delete the bidirectional objects
1130
//aaa.setRefA(null);
1131
//tx.getBroker().store(aaa);
1132
tx.getBroker().delete(a);
1133        tx.commit();
1134    }
1135
1136    /**
1137     * Class Shop has a bidirectional 1:1 reference with ShopDetail
1138     * (FK constraint from SHOP to SHOP_DETAIL table).
1139     * Shop has a m:n relation with Distributor.
1140     */

1141    public void testBidirectionalWithConstraint_2a() throws Exception JavaDoc
1142    {
1143        String JavaDoc name = "testBidirectionalWithConstraint_2a_" + System.currentTimeMillis();
1144
1145        Shop s1 = new Shop(name + "_1");
1146        ShopDetail sd = new ShopDetail(name + "_1");
1147        s1.setDetail(sd);
1148        sd.setShop(s1);
1149        Distributor d1 = new Distributor(name + "_1");
1150        s1.addDistributor(d1);
1151        d1.addShop(s1);
1152
1153        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1154        tx.begin();
1155        database.makePersistent(s1);
1156        tx.commit();
1157
1158        // Now we delete the Shop with ShopDetail, but don't
1159
// touch the Distributor object
1160
tx.begin();
1161        database.deletePersistent(s1);
1162        // flush to avoid constraint error
1163
tx.flush();
1164        database.deletePersistent(sd);
1165        tx.commit();
1166    }
1167
1168    /**
1169     * Class Shop has a bidirectional 1:1 reference with ShopDetail and the DB table of Shop
1170     * has a foreign key constraint on ShopDetail table. Shop has a m:n relation with Distributor.
1171     * <p/>
1172     * If the user take care of the ordering itself the test pass.
1173     */

1174    public void testBidirectionalWithConstraint_2b() throws Exception JavaDoc
1175    {
1176        String JavaDoc name = "testBidirectionalWithConstraint_2c_" + System.currentTimeMillis();
1177
1178        Shop s1 = new Shop(name + "_1");
1179        Distributor d1 = new Distributor(name + "_1");
1180        s1.addDistributor(d1);
1181        d1.addShop(s1);
1182
1183        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1184        tx.begin();
1185        // When using flush() we can add objects step by step
1186
database.makePersistent(s1);
1187        tx.flush();
1188
1189        // add the shop detail object to Shop
1190
ShopDetail sd = new ShopDetail(name + "_1");
1191        s1.setDetail(sd);
1192        sd.setShop(s1);
1193
1194        tx.commit();
1195
1196        // Delete all created objects, we disable implicit
1197
// locking and ordering to avoid constraint error
1198
tx.setImplicitLocking(false);
1199        tx.setOrdering(false);
1200        tx.begin();
1201        database.deletePersistent(d1);
1202        database.deletePersistent(s1);
1203        database.deletePersistent(sd);
1204        tx.commit();
1205    }
1206
1207    /**
1208     * Class Shop has a bidirectional 1:1 reference with ShopDetail and the DB table of Shop
1209     * has a foreign key constraint on ShopDetail table. Shop has a m:n relation with Distributor.
1210     * <p/>
1211     * If the user take care of the ordering itself the test pass.
1212     */

1213    public void testBidirectionalWithConstraint_2d() throws Exception JavaDoc
1214    {
1215        String JavaDoc name = "testBidirectionalWithConstraint_2d_" + System.currentTimeMillis();
1216        Shop s1 = new Shop(name + "_1");
1217        ShopDetail sd = new ShopDetail(name + "_1");
1218        s1.setDetail(sd);
1219        sd.setShop(s1);
1220        Shop s2 = new Shop(name + "_2");
1221        Shop s3 = new Shop(name + "_3");
1222        Distributor d1 = new Distributor(name + "_1");
1223        Distributor d2 = new Distributor(name + "_2");
1224        Distributor d3 = new Distributor(name + "_3");
1225        Distributor d4 = new Distributor(name + "_4");
1226        s1.addDistributor(d1);
1227        d1.addShop(s1);
1228        s1.addDistributor(d2);
1229        d2.addShop(s1);
1230        s1.addDistributor(d3);
1231        d3.addShop(s1); // one
1232
s2.addDistributor(d1);
1233        d1.addShop(s2);
1234        s3.addDistributor(d4);
1235        d4.addShop(s3);
1236        s3.addDistributor(d1);
1237        d1.addShop(s3);
1238        d3.addShop(s2); // two
1239
s2.addDistributor(d3);
1240        d3.addShop(s3); // three
1241
s3.addDistributor(d3);
1242
1243        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1244        tx.begin();
1245        // mandatory to add the ShopDetail object first, because of the ordering bug
1246
database.makePersistent(sd);
1247        database.makePersistent(s1);
1248        database.makePersistent(s2);
1249        database.makePersistent(s3);
1250        tx.commit();
1251
1252        tx.begin();
1253        database.deletePersistent(d1);
1254        database.deletePersistent(s1);
1255        database.deletePersistent(d4);
1256        tx.commit();
1257
1258        tx.begin();
1259        // clear the cache to make this test work with all cache implementations
1260
tx.getBroker().clearCache();
1261
1262        OQLQuery query = odmg.newOQLQuery();
1263        query.create("select shops from " + Shop.class.getName() + " where name like $1");
1264        query.bind(name + "%");
1265        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1266
1267        assertEquals(2, result.size());
1268
1269        query = odmg.newOQLQuery();
1270        query.create("select objects from " + Distributor.class.getName() + " where name like $1");
1271        query.bind(name + "%");
1272        result = (Collection JavaDoc) query.execute();
1273
1274        assertEquals(2, result.size());
1275        tx.commit();
1276
1277        tx.begin();
1278        query = odmg.newOQLQuery();
1279        query.create("select objects from " + Distributor.class.getName() + " where name like $1");
1280        query.bind(name + "_3");
1281        result = (Collection JavaDoc) query.execute();
1282        tx.commit();
1283
1284        assertEquals(1, result.size());
1285        Distributor d3New = (Distributor) result.iterator().next();
1286
1287        assertNotNull(d3New.getShops());
1288        assertEquals(2, d3New.getShops().size());
1289    }
1290
1291    public void testMtoNWithBackReference_2() throws Exception JavaDoc
1292    {
1293        String JavaDoc name = "testMtoNWithBackReference_2_" + System.currentTimeMillis();
1294        Shop s1 = new Shop(name + "_1");
1295        Shop s2 = new Shop(name + "_2");
1296        Shop s3 = new Shop(name + "_3");
1297        Distributor d1 = new Distributor(name + "_1");
1298        Distributor d2 = new Distributor(name + "_2");
1299        Distributor d3 = new Distributor(name + "_3");
1300        Distributor d4 = new Distributor(name + "_4");
1301        s1.addDistributor(d1);
1302        d1.addShop(s1);
1303        s1.addDistributor(d2);
1304        d2.addShop(s1);
1305        s1.addDistributor(d3);
1306        d3.addShop(s1);
1307        s2.addDistributor(d1);
1308        d1.addShop(s2);
1309        s3.addDistributor(d4);
1310        d4.addShop(s3);
1311        s3.addDistributor(d1);
1312        d1.addShop(s3);
1313        d3.addShop(s2);
1314        s2.addDistributor(d3);
1315        d3.addShop(s3);
1316        s3.addDistributor(d3);
1317
1318        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1319        tx.begin();
1320        // madatory to add the ShopDetail object first
1321
database.makePersistent(s1);
1322        database.makePersistent(s2);
1323        database.makePersistent(s3);
1324        tx.commit();
1325
1326        tx.begin();
1327        tx.setCascadingDelete(Distributor.class, "shops", true);
1328        database.deletePersistent(d1);
1329        database.deletePersistent(s1);
1330        database.deletePersistent(d4);
1331        tx.commit();
1332
1333        tx.begin();
1334        // clear cache to make it work with all caching implementations
1335
tx.getBroker().clearCache();
1336        OQLQuery query = odmg.newOQLQuery();
1337        query.create("select shops from " + Shop.class.getName() + " where name like $1");
1338        query.bind(name + "%");
1339        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1340
1341        assertEquals(0, result.size());
1342
1343        query = odmg.newOQLQuery();
1344        query.create("select objects from " + Distributor.class.getName() + " where name like $1");
1345        query.bind(name + "%");
1346        result = (Collection JavaDoc) query.execute();
1347
1348        assertEquals(2, result.size());
1349        tx.commit();
1350
1351        tx.begin();
1352        query = odmg.newOQLQuery();
1353        query.create("select objects from " + Distributor.class.getName() + " where name like $1");
1354        query.bind(name + "_3");
1355        result = (Collection JavaDoc) query.execute();
1356        tx.commit();
1357
1358        assertEquals(1, result.size());
1359        Distributor d3New = (Distributor) result.iterator().next();
1360
1361        assertNotNull(d3New.getShops());
1362        assertEquals(0, d3New.getShops().size());
1363    }
1364
1365    public void testOneToNWithSelfReference_1() throws Exception JavaDoc
1366    {
1367        String JavaDoc name = "testOneToNWithSelfReference_1_" + System.currentTimeMillis();
1368        Shop s = new Shop();
1369        s.setName(name);
1370        Product p1 = new Product();
1371        p1.setName(name + "_product_1");
1372        Product p2 = new Product();
1373        p2.setName(name + "_product_2");
1374
1375        List JavaDoc products = new ArrayList JavaDoc();
1376        products.add(p1);
1377        products.add(p2);
1378
1379        s.setProducts(products);
1380        p1.setShop(s);
1381        p2.setShop(s);
1382
1383        Product p1a = new Product();
1384        p1a.setName(name + "_subProduct_A");
1385        Product p1b = new Product();
1386        p1b.setName(name + "_subProduct_B");
1387        Product p1c = new Product();
1388        p1c.setName(name + "_subProduct_C");
1389
1390        List JavaDoc subProducts = new ArrayList JavaDoc();
1391        subProducts.add(p1a);
1392        subProducts.add(p1b);
1393        subProducts.add(p1c);
1394
1395        p1.setSubProducts(subProducts);
1396
1397        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1398        tx.begin();
1399        database.makePersistent(s);
1400        tx.commit();
1401
1402        tx.begin();
1403        tx.getBroker().clearCache();
1404
1405        OQLQuery query = odmg.newOQLQuery();
1406        query.create("select products from " + Shop.class.getName() + " where name like $1");
1407        query.bind(name + "%");
1408        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1409        tx.commit();
1410
1411        assertEquals(1, result.size());
1412        Shop newShop = (Shop) result.iterator().next();
1413        assertNotNull(newShop.getProducts());
1414        assertEquals(2, newShop.getProducts().size());
1415
1416        boolean match = false;
1417        for(Iterator JavaDoc iterator = newShop.getProducts().iterator(); iterator.hasNext();)
1418        {
1419            Product p = (Product) iterator.next();
1420            if(p.getSubProducts() != null && p.getSubProducts().size() > 0)
1421            {
1422                match = true;
1423                assertEquals(3, p.getSubProducts().size());
1424            }
1425        }
1426        assertTrue("Sub products aren't stored", match);
1427
1428        tx.begin();
1429        database.deletePersistent(s);
1430        tx.commit();
1431
1432
1433        tx.begin();
1434        tx.getBroker().clearCache();
1435        query = odmg.newOQLQuery();
1436        query.create("select products from " + Product.class.getName() + " where name like $1");
1437        query.bind(name + "_subPro%");
1438        result = (Collection JavaDoc) query.execute();
1439        tx.commit();
1440        assertEquals(3, result.size());
1441
1442        tx.begin();
1443        query = odmg.newOQLQuery();
1444        query.create("select products from " + Product.class.getName() + " where name like $1");
1445        query.bind(name + "_product_1");
1446        result = (Collection JavaDoc) query.execute();
1447        assertEquals(1, result.size());
1448
1449        database.deletePersistent(result.iterator().next());
1450        tx.commit();
1451
1452
1453        tx.begin();
1454        tx.getBroker().clearCache();
1455        query = odmg.newOQLQuery();
1456        query.create("select products from " + Product.class.getName() + " where name like $1");
1457        query.bind(name + "_subPro%");
1458        result = (Collection JavaDoc) query.execute();
1459        tx.commit();
1460        assertEquals(3, result.size());
1461    }
1462
1463    public void testOneToNWithSelfReference_2() throws Exception JavaDoc
1464    {
1465        String JavaDoc name = "testOneToNWithSelfReference_2_" + System.currentTimeMillis();
1466        Shop s = new Shop();
1467        s.setName(name);
1468        Product p1 = new Product();
1469        p1.setName(name + "_product_1");
1470        Product p2 = new Product();
1471        p2.setName(name + "_product_2");
1472
1473        List JavaDoc products = new ArrayList JavaDoc();
1474        products.add(p1);
1475        products.add(p2);
1476
1477        s.setProducts(products);
1478        p1.setShop(s);
1479        p2.setShop(s);
1480
1481        Product p1a = new Product();
1482        p1a.setName(name + "_subProduct_A");
1483        Product p1b = new Product();
1484        p1b.setName(name + "_subProduct_B");
1485        Product p1c = new Product();
1486        p1c.setName(name + "_subProduct_C");
1487
1488        List JavaDoc subProducts = new ArrayList JavaDoc();
1489        subProducts.add(p1a);
1490        subProducts.add(p1b);
1491        subProducts.add(p1c);
1492
1493        p1.setSubProducts(subProducts);
1494
1495        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1496        tx.begin();
1497        database.makePersistent(s);
1498        tx.commit();
1499
1500        tx.begin();
1501        tx.getBroker().clearCache();
1502
1503        OQLQuery query = odmg.newOQLQuery();
1504        query.create("select products from " + Shop.class.getName() + " where name like $1");
1505        query.bind(name + "%");
1506        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1507        tx.commit();
1508
1509        assertEquals(1, result.size());
1510        Shop newShop = (Shop) result.iterator().next();
1511        assertNotNull(newShop.getProducts());
1512        assertEquals(2, newShop.getProducts().size());
1513
1514        boolean match = false;
1515        for(Iterator JavaDoc iterator = newShop.getProducts().iterator(); iterator.hasNext();)
1516        {
1517            Product p = (Product) iterator.next();
1518            if(p.getSubProducts() != null && p.getSubProducts().size() > 0)
1519            {
1520                match = true;
1521                assertEquals(3, p.getSubProducts().size());
1522            }
1523        }
1524        assertTrue("Sub products aren't stored", match);
1525
1526        tx.begin();
1527        // now we enable cascading delete
1528
tx.setCascadingDelete(Shop.class, true);
1529        database.deletePersistent(s);
1530        tx.commit();
1531
1532
1533        tx.begin();
1534        tx.getBroker().clearCache();
1535        query = odmg.newOQLQuery();
1536        query.create("select products from " + Product.class.getName() + " where name like $1");
1537        query.bind(name + "_subPro%");
1538        result = (Collection JavaDoc) query.execute();
1539        assertEquals(3, result.size());
1540
1541        query = odmg.newOQLQuery();
1542        query.create("select products from " + Product.class.getName() + " where name like $1");
1543        query.bind(name + "_product_1");
1544        result = (Collection JavaDoc) query.execute();
1545        assertEquals(0, result.size());
1546
1547        tx.commit();
1548    }
1549
1550    public void testOneToNWithSelfReference_3() throws Exception JavaDoc
1551    {
1552        String JavaDoc name = "testOneToNWithSelfReference_3_" + System.currentTimeMillis();
1553        Shop s = new Shop();
1554        s.setName(name);
1555        Product p1 = new Product();
1556        p1.setName(name + "_product_1");
1557        Product p2 = new Product();
1558        p2.setName(name + "_product_2");
1559
1560        List JavaDoc products = new ArrayList JavaDoc();
1561        products.add(p1);
1562        products.add(p2);
1563
1564        s.setProducts(products);
1565        p1.setShop(s);
1566        p2.setShop(s);
1567
1568        Product p1a = new Product();
1569        p1a.setName(name + "_subProduct_A");
1570        Product p1b = new Product();
1571        p1b.setName(name + "_subProduct_B");
1572        Product p1c = new Product();
1573        p1c.setName(name + "_subProduct_C");
1574
1575        List JavaDoc subProducts = new ArrayList JavaDoc();
1576        subProducts.add(p1a);
1577        subProducts.add(p1b);
1578        subProducts.add(p1c);
1579
1580        p1.setSubProducts(subProducts);
1581
1582        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1583        tx.begin();
1584        database.makePersistent(s);
1585        tx.commit();
1586
1587        tx.begin();
1588        tx.getBroker().clearCache();
1589
1590        OQLQuery query = odmg.newOQLQuery();
1591        query.create("select products from " + Shop.class.getName() + " where name like $1");
1592        query.bind(name + "%");
1593        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1594        tx.commit();
1595
1596        assertEquals(1, result.size());
1597        Shop newShop = (Shop) result.iterator().next();
1598        assertNotNull(newShop.getProducts());
1599        assertEquals(2, newShop.getProducts().size());
1600
1601        boolean match = false;
1602        for(Iterator JavaDoc iterator = newShop.getProducts().iterator(); iterator.hasNext();)
1603        {
1604            Product p = (Product) iterator.next();
1605            if(p.getSubProducts() != null && p.getSubProducts().size() > 0)
1606            {
1607                match = true;
1608                assertEquals(3, p.getSubProducts().size());
1609            }
1610        }
1611        assertTrue("Sub products aren't stored", match);
1612
1613        tx.begin();
1614        // now we enable cascading delete
1615
tx.setCascadingDelete(Shop.class, true);
1616        tx.setCascadingDelete(Product.class, true);
1617        database.deletePersistent(s);
1618        tx.commit();
1619
1620
1621        tx.begin();
1622        tx.getBroker().clearCache();
1623        query = odmg.newOQLQuery();
1624        query.create("select products from " + Product.class.getName() + " where name like $1");
1625        query.bind(name + "_subPro%");
1626        result = (Collection JavaDoc) query.execute();
1627        assertEquals(0, result.size());
1628
1629        query = odmg.newOQLQuery();
1630        query.create("select products from " + Product.class.getName() + " where name like $1");
1631        query.bind(name + "_product_1");
1632        result = (Collection JavaDoc) query.execute();
1633        assertEquals(0, result.size());
1634
1635        tx.commit();
1636    }
1637
1638    public void testOneToOneWithBackReference_1() throws Exception JavaDoc
1639    {
1640        String JavaDoc name = "testOneToOneWithBackReference_1_" + System.currentTimeMillis();
1641        Shop s = new Shop();
1642        s.setName(name);
1643        ShopDetail sd = new ShopDetail();
1644        sd.setName(name);
1645        s.setDetail(sd);
1646        sd.setShop(s);
1647
1648        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1649        tx.begin();
1650        database.makePersistent(s);
1651        // before establishing the circular references write
1652
// all objects to DB
1653
tx.flush();
1654        // now close the circular references
1655
tx.commit();
1656
1657        tx.begin();
1658        tx.getBroker().clearCache();
1659
1660        OQLQuery query = odmg.newOQLQuery();
1661        query.create("select detail from " + ShopDetail.class.getName() + " where name like $1");
1662        query.bind(name);
1663        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1664        tx.commit();
1665
1666        assertEquals(1, result.size());
1667        ShopDetail sdNew = (ShopDetail) result.iterator().next();
1668        assertNotNull(sdNew.getShop());
1669
1670        tx.begin();
1671        tx.lock(sdNew, Transaction.WRITE);
1672        Shop tmp = sdNew.getShop();
1673        // it's bidirectional, so remove this references first
1674
tmp.setDetail(null);
1675        sdNew.setShop(null);
1676        database.deletePersistent(tmp);
1677        tx.flush();
1678
1679        query = odmg.newOQLQuery();
1680        query.create("select detail from " + ShopDetail.class.getName() + " where name like $1");
1681        query.bind(name);
1682        result = (Collection JavaDoc) query.execute();
1683        assertEquals(1, result.size());
1684        ShopDetail newSd = (ShopDetail) result.iterator().next();
1685        assertNotNull(newSd);
1686        assertNull(newSd.getShop());
1687        tx.commit();
1688
1689        tx.begin();
1690        query = odmg.newOQLQuery();
1691        query.create("select shops from " + Shop.class.getName() + " where name like $1");
1692        query.bind(name);
1693        Collection JavaDoc resultShop = (Collection JavaDoc) query.execute();
1694        assertEquals(0, resultShop.size());
1695
1696        // delete ShopDetail too
1697
database.deletePersistent(newSd);
1698        tx.commit();
1699    }
1700
1701    public void testOneToOneWithBackReference_3() throws Exception JavaDoc
1702    {
1703        String JavaDoc name = "testOneToOneWithBackReference_3_" + System.currentTimeMillis();
1704        Shop s = new Shop();
1705        s.setName(name);
1706        ShopDetail sd = new ShopDetail();
1707        sd.setName(name);
1708        s.setDetail(sd);
1709        sd.setShop(s);
1710
1711        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1712        tx.begin();
1713        database.makePersistent(s);
1714        database.deletePersistent(s);
1715        database.makePersistent(s);
1716        tx.commit();
1717
1718        tx.begin();
1719        OQLQuery query = odmg.newOQLQuery();
1720        query.create("select shops from " + Shop.class.getName() + " where name like $1");
1721        query.bind(name);
1722        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1723        tx.commit();
1724
1725        assertEquals(1, result.size());
1726        Shop newShop = (Shop) result.iterator().next();
1727        assertNotNull(newShop.getDetail());
1728
1729        tx.begin();
1730        database.deletePersistent(newShop);
1731        // add object again, we expect that nothing was deleted
1732
database.makePersistent(newShop);
1733        // flush changes to DB, we don't change anything
1734
tx.flush();
1735        query = odmg.newOQLQuery();
1736        query.create("select shops from " + Shop.class.getName() + " where name like $1");
1737        query.bind(name);
1738        result = (Collection JavaDoc) query.execute();
1739        tx.commit();
1740
1741        assertEquals(1, result.size());
1742        Shop tmp = (Shop) result.iterator().next();
1743        assertNotNull(tmp.getDetail());
1744
1745        tx.begin();
1746        database.deletePersistent(newShop);
1747        database.makePersistent(newShop);
1748        database.deletePersistent(newShop);
1749        tx.flush();
1750        database.deletePersistent(newShop.getDetail());
1751        tx.flush();
1752
1753        query = odmg.newOQLQuery();
1754        query.create("select detail from " + ShopDetail.class.getName() + " where name like $1");
1755        query.bind(name);
1756        result = (Collection JavaDoc) query.execute();
1757        assertEquals(0, result.size());
1758
1759        query = odmg.newOQLQuery();
1760        query.create("select shops from " + Shop.class.getName() + " where name like $1");
1761        query.bind(name);
1762        result = (Collection JavaDoc) query.execute();
1763        assertEquals(0, result.size());
1764        tx.commit();
1765
1766        tx.begin();
1767        query = odmg.newOQLQuery();
1768        query.create("select detail from " + ShopDetail.class.getName() + " where name like $1");
1769        query.bind(name);
1770        result = (Collection JavaDoc) query.execute();
1771        assertEquals(0, result.size());
1772
1773        query = odmg.newOQLQuery();
1774        query.create("select shops from " + Shop.class.getName() + " where name like $1");
1775        query.bind(name);
1776        result = (Collection JavaDoc) query.execute();
1777        assertEquals(0, result.size());
1778        tx.commit();
1779    }
1780
1781    public void testOneToOneWithBackReference_2() throws Exception JavaDoc
1782    {
1783        String JavaDoc name = "testOneToOneWithBackReference_2_" + System.currentTimeMillis();
1784        Shop s = new Shop();
1785        s.setName(name);
1786        ShopDetail sd = new ShopDetail();
1787        sd.setName(name);
1788        s.setDetail(sd);
1789        sd.setShop(s);
1790
1791        TransactionExt tx = (TransactionExt) odmg.newTransaction();
1792        tx.begin();
1793        database.makePersistent(s);
1794        // shop and shopDetail have a bidirectional 1:1 reference
1795
// on flush() OJB will insert both objects and set one FK
1796
tx.flush();
1797        // on commit() OJB will be aware of the bidirectional reference
1798
// and set the second FK
1799
tx.commit();
1800
1801        tx.begin();
1802        tx.getBroker().clearCache();
1803
1804        OQLQuery query = odmg.newOQLQuery();
1805        query.create("select detail from " + ShopDetail.class.getName() + " where name like $1");
1806        query.bind(name);
1807        Collection JavaDoc result = (Collection JavaDoc) query.execute();
1808        tx.commit();
1809
1810        assertEquals(1, result.size());
1811        ShopDetail sdNew = (ShopDetail) result.iterator().next();
1812        assertNotNull(sdNew.getShop());
1813
1814        tx.begin();
1815        // cascading delete should delete Shop too
1816
tx.setCascadingDelete(ShopDetail.class, true);
1817        database.deletePersistent(sdNew);
1818        tx.flush();
1819
1820        query = odmg.newOQLQuery();
1821        query.create("select detail from " + ShopDetail.class.getName() + " where name like $1");
1822        query.bind(name);
1823        result = (Collection JavaDoc) query.execute();
1824        tx.commit();
1825        assertEquals(0, result.size());
1826
1827        tx.begin();
1828        query = odmg.newOQLQuery();
1829        query.create("select detail from " + Shop.class.getName() + " where name like $1");
1830        query.bind(name);
1831        result = (Collection JavaDoc) query.execute();
1832        assertEquals(0, result.size());
1833        tx.commit();
1834    }
1835
1836    public static class Shop
1837    {
1838        private Integer JavaDoc id;
1839        private String JavaDoc name;
1840        private ShopDetail detail;
1841        private List JavaDoc products;
1842        private List JavaDoc distributors;
1843
1844        public Shop()
1845        {
1846        }
1847
1848        public Shop(String JavaDoc name)
1849        {
1850            this.name = name;
1851        }
1852
1853        public Integer JavaDoc getId()
1854        {
1855            return id;
1856        }
1857
1858        public void setId(Integer JavaDoc id)
1859        {
1860            this.id = id;
1861        }
1862
1863        public String JavaDoc getName()
1864        {
1865            return name;
1866        }
1867
1868        public void setName(String JavaDoc name)
1869        {
1870            this.name = name;
1871        }
1872
1873        public ShopDetail getDetail()
1874        {
1875            return detail;
1876        }
1877
1878        public void setDetail(ShopDetail detail)
1879        {
1880            this.detail = detail;
1881        }
1882
1883        public List JavaDoc getProducts()
1884        {
1885            return products;
1886        }
1887
1888        public void setProducts(List JavaDoc products)
1889        {
1890            this.products = products;
1891        }
1892
1893        public List JavaDoc getDistributors()
1894        {
1895            return distributors;
1896        }
1897
1898        public void setDistributors(List JavaDoc distributors)
1899        {
1900            this.distributors = distributors;
1901        }
1902
1903        public void addDistributor(Distributor d)
1904        {
1905            if(this.distributors == null)
1906            {
1907                this.distributors = new ArrayList JavaDoc();
1908            }
1909            this.distributors.add(d);
1910        }
1911    }
1912
1913    public static class Distributor
1914    {
1915        private Integer JavaDoc id;
1916        private String JavaDoc name;
1917        private List JavaDoc shops;
1918
1919        public Distributor()
1920        {
1921        }
1922
1923        public Distributor(String JavaDoc name)
1924        {
1925            this.name = name;
1926        }
1927
1928        public Integer JavaDoc getId()
1929        {
1930            return id;
1931        }
1932
1933        public void setId(Integer JavaDoc id)
1934        {
1935            this.id = id;
1936        }
1937
1938        public String JavaDoc getName()
1939        {
1940            return name;
1941        }
1942
1943        public void setName(String JavaDoc name)
1944        {
1945            this.name = name;
1946        }
1947
1948        public List JavaDoc getShops()
1949        {
1950            return shops;
1951        }
1952
1953        public void setShops(List JavaDoc shops)
1954        {
1955            this.shops = shops;
1956        }
1957
1958        public void addShop(Shop s)
1959        {
1960            if(this.shops == null)
1961            {
1962                this.shops = new ArrayList JavaDoc();
1963            }
1964            this.shops.add(s);
1965        }
1966    }
1967
1968    public static class Product
1969    {
1970        private Integer JavaDoc id;
1971        private String JavaDoc name;
1972        private Shop shop;
1973        private Integer JavaDoc shopFk;
1974        private List JavaDoc subProducts;
1975        private Integer JavaDoc subProductFK;
1976
1977        public Product()
1978        {
1979        }
1980
1981        public Product(String JavaDoc name)
1982        {
1983            this.name = name;
1984        }
1985
1986        public Integer JavaDoc getId()
1987        {
1988            return id;
1989        }
1990
1991        public void setId(Integer JavaDoc id)
1992        {
1993            this.id = id;
1994        }
1995
1996        public String JavaDoc getName()
1997        {
1998            return name;
1999        }
2000
2001        public void setName(String JavaDoc name)
2002        {
2003            this.name = name;
2004        }
2005
2006        public Shop getShop()
2007        {
2008            return shop;
2009        }
2010
2011        public void setShop(Shop shop)
2012        {
2013            this.shop = shop;
2014        }
2015
2016        public Integer JavaDoc getShopFk()
2017        {
2018            return shopFk;
2019        }
2020
2021        public void setShopFk(Integer JavaDoc shopFk)
2022        {
2023            this.shopFk = shopFk;
2024        }
2025
2026        public Integer JavaDoc getSubProductFK()
2027        {
2028            return subProductFK;
2029        }
2030
2031        public void setSubProductFK(Integer JavaDoc subProductFK)
2032        {
2033            this.subProductFK = subProductFK;
2034        }
2035
2036        public void addSubProduct(Product p)
2037        {
2038            if(subProducts == null)
2039            {
2040                subProducts = new ArrayList JavaDoc();
2041            }
2042            subProducts.add(p);
2043        }
2044
2045        public List JavaDoc getSubProducts()
2046        {
2047            return subProducts;
2048        }
2049
2050        public void setSubProducts(List JavaDoc subProducts)
2051        {
2052            this.subProducts = subProducts;
2053        }
2054    }
2055
2056    public static class ShopDetail
2057    {
2058        private Integer JavaDoc id;
2059        private String JavaDoc name;
2060        private Shop shop;
2061
2062        public ShopDetail()
2063        {
2064        }
2065
2066        public ShopDetail(String JavaDoc name)
2067        {
2068            this.name = name;
2069        }
2070
2071        public Integer JavaDoc getId()
2072        {
2073            return id;
2074        }
2075
2076        public void setId(Integer JavaDoc id)
2077        {
2078            this.id = id;
2079        }
2080
2081        public String JavaDoc getName()
2082        {
2083            return name;
2084        }
2085
2086        public void setName(String JavaDoc name)
2087        {
2088            this.name = name;
2089        }
2090
2091        public Shop getShop()
2092        {
2093            return shop;
2094        }
2095
2096        public void setShop(Shop shop)
2097        {
2098            this.shop = shop;
2099        }
2100    }
2101
2102    abstract static class BaseObject
2103    {
2104        private Integer JavaDoc id;
2105        private String JavaDoc name;
2106        private String JavaDoc ojbConcreteClass;
2107
2108        public BaseObject()
2109        {
2110            this.ojbConcreteClass = this.getClass().getName();
2111        }
2112
2113        public BaseObject(String JavaDoc name)
2114        {
2115            this();
2116            this.name = name;
2117        }
2118
2119        public Integer JavaDoc getId()
2120        {
2121            return id;
2122        }
2123
2124        public void setId(Integer JavaDoc id)
2125        {
2126            this.id = id;
2127        }
2128
2129        public String JavaDoc getName()
2130        {
2131            return name;
2132        }
2133
2134        public void setName(String JavaDoc name)
2135        {
2136            this.name = name;
2137        }
2138
2139        public String JavaDoc getOjbConcreteClass()
2140        {
2141            return ojbConcreteClass;
2142        }
2143
2144        public void setOjbConcreteClass(String JavaDoc ojbConcreteClass)
2145        {
2146            this.ojbConcreteClass = ojbConcreteClass;
2147        }
2148    }
2149
2150    public static class ObjectA extends BaseObject
2151    {
2152        private ObjectAA refAA;
2153
2154        public ObjectA()
2155        {
2156        }
2157
2158        public ObjectA(String JavaDoc name)
2159        {
2160            super(name);
2161        }
2162
2163        public ObjectAA getRefAA()
2164        {
2165            return refAA;
2166        }
2167
2168        public void setRefAA(ObjectAA refAA)
2169        {
2170            this.refAA = refAA;
2171        }
2172    }
2173
2174    public static class ObjectAA extends BaseObject
2175    {
2176        private ObjectAAA refAAA;
2177
2178        public ObjectAA()
2179        {
2180        }
2181
2182        public ObjectAA(String JavaDoc name)
2183        {
2184            super(name);
2185        }
2186
2187        public ObjectAAA getRefAAA()
2188        {
2189            return refAAA;
2190        }
2191
2192        public void setRefAAA(ObjectAAA refAAA)
2193        {
2194            this.refAAA = refAAA;
2195        }
2196    }
2197
2198    public static class ObjectAAA extends BaseObject
2199    {
2200        private ObjectAAAA refAAAA;
2201        private ObjectA refA;
2202
2203        public ObjectAAA()
2204        {
2205        }
2206
2207        public ObjectAAA(String JavaDoc name)
2208        {
2209            super(name);
2210        }
2211
2212        public ObjectAAAA getRefAAAA()
2213        {
2214            return refAAAA;
2215        }
2216
2217        public void setRefAAAA(ObjectAAAA refAAAA)
2218        {
2219            this.refAAAA = refAAAA;
2220        }
2221
2222        public ObjectA getRefA()
2223        {
2224            return refA;
2225        }
2226
2227        public void setRefA(ObjectA refA)
2228        {
2229            this.refA = refA;
2230        }
2231    }
2232
2233    public static class ObjectAAAA extends BaseObject
2234    {
2235        private ObjectA refA;
2236
2237        public ObjectAAAA()
2238        {
2239        }
2240
2241        public ObjectAAAA(String JavaDoc name)
2242        {
2243            super(name);
2244        }
2245
2246        public ObjectA getRefA()
2247        {
2248            return refA;
2249        }
2250
2251        public void setRefA(ObjectA refA)
2252        {
2253            this.refA = refA;
2254        }
2255    }
2256}
2257
Popular Tags