001: /**
002: * Author: Matthew Baird
003: * mattbaird@yahoo.com
004: */package org.apache.ojb.odmg;
005:
006: import java.util.Iterator;
007: import java.util.Collection;
008: import java.io.Serializable;
009:
010: import org.apache.ojb.junit.ODMGTestCase;
011: import org.odmg.ODMGException;
012: import org.odmg.OQLQuery;
013: import org.odmg.Transaction;
014:
015: /**
016: * Tests a bidirectional association A<-->B
017: * @see org.apache.ojb.broker.BidirectionalAssociationTest for equivalent test in PB API
018: */
019: public class BidirectionalAssociationTest extends ODMGTestCase {
020: public static void main(String[] args) {
021: String[] arr = { BidirectionalAssociationTest.class.getName() };
022: junit.textui.TestRunner.main(arr);
023: }
024:
025: public void testDeleteA() throws Exception {
026: /**
027: * create at least one A/B
028: */
029: createWithUpdate();
030: deleteA();
031: }
032:
033: public void testDeleteB() throws Exception {
034: /**
035: * create at least one A/B
036: */
037: createWithUpdate();
038: deleteB();
039: }
040:
041: public void testCreateWitUpdate() throws Exception {
042: createWithUpdate();
043: }
044:
045: /**
046: * test that we can create 2 objects that have a bidirectional association in ODMG API
047: */
048: public void createWithUpdate() throws ODMGException {
049: Transaction tx = odmg.newTransaction();
050: long currentTime = System.currentTimeMillis();
051:
052: ObjectA a = new ObjectA();
053: a.setPk("A" + currentTime);
054: ObjectB b = new ObjectB();
055: b.setPk("B" + currentTime);
056:
057: tx.begin();
058: database.makePersistent(a);
059: database.makePersistent(b);
060: tx.commit();
061:
062: tx.begin();
063: tx.lock(a, Transaction.WRITE);
064: tx.lock(b, Transaction.WRITE);
065: a.setRelatedB(b);
066: b.setRelatedA(a);
067: tx.commit();
068:
069: /**
070: * now make sure they are in db, A first, then B
071: */
072: tx.begin();
073: OQLQuery query = odmg.newOQLQuery();
074: int i = 0;
075: query.create("select bidirectionalAssociationObjectA from "
076: + ObjectA.class.getName() + " where pk=$1");
077: query.bind("A" + currentTime);
078: Collection all = (Collection) query.execute();
079: Iterator it = all.iterator();
080: while (it.hasNext()) {
081: i++;
082: a = (ObjectA) it.next();
083: if (a.getRelatedB() == null)
084: fail("a should have had a related b");
085: }
086: if (i > 1)
087: fail("should have found only one bidirectionalAssociationObjectA, instead found: "
088: + i);
089:
090: query = odmg.newOQLQuery();
091: i = 0;
092: query.create("select bidirectionalAssociationObjectB from "
093: + ObjectB.class.getName() + " where pk=$1");
094: query.bind("B" + currentTime);
095: all = (Collection) query.execute();
096: it = all.iterator();
097: while (it.hasNext()) {
098: i++;
099: b = (ObjectB) it.next();
100: if (b.getRelatedA() == null)
101: fail("b should have had a related a");
102:
103: }
104: if (i > 1)
105: fail("should have found only one bidirectionalAssociationObjectB, instead found: "
106: + i);
107: tx.commit();
108: }
109:
110: /**
111: * this test doesn't work as OJB won't do the insert then execute the update.
112: * @throws ODMGException
113: */
114: public void testCreateWithoutUpdate() throws ODMGException {
115: Transaction tx = odmg.newTransaction();
116: long currentTime = System.currentTimeMillis();
117: ObjectA a = new ObjectA();
118: a.setPk("A" + currentTime);
119: ObjectB b = new ObjectB();
120: b.setPk("B" + currentTime);
121:
122: tx.begin();
123: b.setRelatedA(a);
124: a.setRelatedB(b);
125: // we use a FK from ObjectB to ObjectA, thus we
126: // make persistent B
127: database.makePersistent(b);
128: // not needed
129: //database.makePersistent(a);
130: tx.commit();
131:
132: /**
133: * now make sure they are in db, A first, then B
134: */
135: tx.begin();
136: OQLQuery query = odmg.newOQLQuery();
137: int i = 0;
138: query.create("select bidirectionalAssociationObjectA from "
139: + ObjectA.class.getName() + " where pk=$1");
140: query.bind("A" + currentTime);
141: Collection all = (Collection) query.execute();
142: Iterator it = all.iterator();
143: while (it.hasNext()) {
144: i++;
145: it.next();
146: }
147: if (i > 1)
148: fail("should have found only one bidirectionalAssociationObjectA, instead found: "
149: + i);
150:
151: query = odmg.newOQLQuery();
152: i = 0;
153: query.create("select bidirectionalAssociationObjectB from "
154: + ObjectB.class.getName() + " where pk=$1");
155: query.bind("B" + currentTime);
156: all = (Collection) query.execute();
157: it = all.iterator();
158: while (it.hasNext()) {
159: i++;
160: it.next();
161: }
162: if (i > 1)
163: fail("should have found only one bidirectionalAssociationObjectB, instead found: "
164: + i);
165:
166: }
167:
168: /**
169: * no clue why this isn't working.
170: * @throws Exception
171: */
172: public void testGetA() throws Exception {
173: /**
174: * create at least one A/B combo
175: */
176: deleteA();
177: deleteB();
178: createWithUpdate();
179:
180: OQLQuery query = odmg.newOQLQuery();
181: int i = 0;
182: query.create("select allA from " + ObjectA.class.getName());
183: Transaction tx = odmg.newTransaction();
184: tx.begin();
185: Collection all = (Collection) query.execute();
186: Iterator it = all.iterator();
187: ObjectA temp = null;
188: while (it.hasNext()) {
189: temp = (ObjectA) it.next();
190: if (temp.getRelatedB() == null)
191: fail("should have relatedB");
192: i++;
193: }
194: tx.commit();
195: if (i == 0)
196: fail("Should have found at least 1 bidirectionalAssociationObjectA object");
197: }
198:
199: public void testGetB() throws Exception {
200: /**
201: * create at least one A/B combo
202: */
203: deleteA();
204: deleteB();
205: createWithUpdate();
206:
207: OQLQuery query = odmg.newOQLQuery();
208: int i = 0;
209: query.create("select bidirectionalAssociationObjectB from "
210: + ObjectB.class.getName());
211: Transaction tx = odmg.newTransaction();
212: tx.begin();
213: Collection all = (Collection) query.execute();
214: Iterator it = all.iterator();
215: ObjectB temp = null;
216: while (it.hasNext()) {
217: temp = (ObjectB) it.next();
218: if (temp.getRelatedA() == null)
219: fail("should have relatedA");
220: i++;
221: }
222: tx.commit();
223: if (i == 0)
224: fail("Should have found at least 1 bidirectionalAssociationObjectA object");
225: }
226:
227: /**
228: * test deleting an object participating in a bidirectional associative relationship. Will throw if it can't delete.
229: * @throws Exception
230: */
231: public void deleteA() throws Exception {
232: ObjectA a;
233: ObjectB b;
234:
235: OQLQuery query = odmg.newOQLQuery();
236: query.create("select bidirectionalAssociationObjectA from "
237: + ObjectA.class.getName());
238: TransactionExt tx = (TransactionExt) odmg.newTransaction();
239: tx.begin();
240: Collection all = (Collection) query.execute();
241: Iterator it = all.iterator();
242:
243: while (it.hasNext()) {
244: a = (ObjectA) it.next();
245: b = a.getRelatedB();
246: if (b != null) {
247: tx.lock(b, Transaction.WRITE);
248: b.setRelatedA(null); // break relationship to avoid ri violation
249: }
250: database.deletePersistent(a);
251: }
252: tx.commit();
253: }
254:
255: /**
256: * test deleting an object participating in a bidirectional associative relationship. Will throw if it can't delete.
257: * @throws Exception
258: */
259: public void deleteB() throws Exception {
260: ObjectA a;
261: ObjectB b;
262:
263: OQLQuery query = odmg.newOQLQuery();
264: query.create("select bidirectionalAssociationObjectB from "
265: + ObjectB.class.getName());
266: Transaction tx = odmg.newTransaction();
267: tx.begin();
268: Collection all = (Collection) query.execute();
269: Iterator it = all.iterator();
270:
271: while (it.hasNext()) {
272: b = (ObjectB) it.next();
273: a = b.getRelatedA();
274: if (a != null) {
275: tx.lock(a, Transaction.WRITE);
276: a.setRelatedB(null); // break relationship to avoid ri violation
277: }
278: database.deletePersistent(b);
279: }
280:
281: tx.commit();
282: }
283:
284: /**
285: * Insert the method's description here.
286: * Creation date: (24.12.2000 00:33:40)
287: */
288: public BidirectionalAssociationTest(String name) {
289: super (name);
290: }
291:
292: public void tearDown() throws Exception {
293: super .tearDown();
294: }
295:
296: public static class ObjectA implements Serializable {
297: private String pk;
298: private String fkToB;
299: private ObjectB relatedB;
300:
301: public ObjectA() {
302: }
303:
304: public String getPk() {
305: return pk;
306: }
307:
308: public void setPk(String pk) {
309: this .pk = pk;
310: }
311:
312: public String getFkToB() {
313: return fkToB;
314: }
315:
316: public void setFkToB(String fkToB) {
317: this .fkToB = fkToB;
318: }
319:
320: public ObjectB getRelatedB() {
321: return relatedB;
322: }
323:
324: public void setRelatedB(ObjectB relatedB) {
325: this .relatedB = relatedB;
326: }
327: }
328:
329: public static class ObjectB implements Serializable {
330: private String pk;
331: private String fkToA;
332: private ObjectA relatedA;
333:
334: public ObjectB() {
335: }
336:
337: public String getPk() {
338: return pk;
339: }
340:
341: public void setPk(String pk) {
342: this .pk = pk;
343: }
344:
345: public String getFkToA() {
346: return fkToA;
347: }
348:
349: public void setFkToA(String fkToA) {
350: this .fkToA = fkToA;
351: }
352:
353: public ObjectA getRelatedA() {
354: return relatedA;
355: }
356:
357: public void setRelatedA(ObjectA relatedA) {
358: this.relatedA = relatedA;
359: }
360: }
361: }
|