001: package org.apache.ojb.otm;
002:
003: /* Copyright 2002-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import java.sql.Timestamp;
019: import java.util.Collection;
020: import java.util.Iterator;
021:
022: import org.apache.ojb.broker.Article;
023: import org.apache.ojb.broker.Contract;
024: import org.apache.ojb.broker.Effectiveness;
025: import org.apache.ojb.broker.Identity;
026: import org.apache.ojb.broker.PBFactoryException;
027: import org.apache.ojb.broker.PersistenceBrokerException;
028: import org.apache.ojb.broker.PersistenceBrokerFactory;
029: import org.apache.ojb.broker.ProductGroup;
030: import org.apache.ojb.broker.RelatedToContract;
031: import org.apache.ojb.broker.Version;
032: import org.apache.ojb.broker.query.Criteria;
033: import org.apache.ojb.broker.query.Query;
034: import org.apache.ojb.broker.query.QueryFactory;
035: import org.apache.ojb.odmg.shared.TestClassA;
036: import org.apache.ojb.odmg.shared.TestClassB;
037: import org.apache.ojb.otm.core.Transaction;
038: import org.apache.ojb.otm.core.TransactionException;
039: import org.apache.ojb.otm.lock.LockType;
040: import org.apache.ojb.otm.lock.LockingException;
041: import org.apache.ojb.junit.OJBTestCase;
042:
043: /**
044: * User: Matthew Baird
045: * Date: Jun 21, 2003
046: * Time: 3:59:08 PM
047: * @version $Id: SwizzleTests.java,v 1.15.2.4 2005/12/21 22:32:01 tomdz Exp $
048: */
049: public class SwizzleTests extends OJBTestCase {
050: private static Class CLASS = SwizzleTests.class;
051: private TestKit _kit;
052: private OTMConnection _conn;
053: private static final int COUNT = 1;
054: private static final long TIME = System.currentTimeMillis();
055:
056: public void setUp() throws Exception {
057: super .setUp();
058: ojbChangeReferenceSetting(TestClassA.class, "b", true, true,
059: true, false);
060: ojbChangeReferenceSetting(TestClassB.class, "a", true, true,
061: true, false);
062: ojbChangeReferenceSetting(ProductGroup.class,
063: "allArticlesInGroup", true, true, true, false);
064: ojbChangeReferenceSetting(Article.class, "productGroup", true,
065: true, true, false);
066: _kit = TestKit.getTestInstance();
067: _conn = _kit.acquireConnection(PersistenceBrokerFactory
068: .getDefaultKey());
069: }
070:
071: public void tearDown() throws Exception {
072: _conn.close();
073: _conn = null;
074: super .tearDown();
075: }
076:
077: public static void main(String[] args) {
078: String[] arr = { CLASS.getName() };
079: junit.textui.TestRunner.main(arr);
080: }
081:
082: public void testSwizzle() throws TransactionException,
083: LockingException, PBFactoryException,
084: PersistenceBrokerException {
085: deleteAllData();
086: createTestData();
087: /**
088: * first get the contract object.
089: */
090: PersistenceBrokerFactory.defaultPersistenceBroker()
091: .clearCache();
092: Transaction tx = _kit.getTransaction(_conn);
093: tx.begin();
094: Criteria crit = new Criteria();
095: crit.addEqualTo("pk", "C" + TIME);
096: Query q = QueryFactory.newQuery(Contract.class, crit);
097: Iterator it = _conn.getIteratorByQuery(q, LockType.WRITE_LOCK);
098: Object retval = null;
099: RelatedToContract r2c = new RelatedToContract();
100: r2c.setPk("R2C" + TIME);
101: r2c.setRelatedValue1("matt");
102: r2c.setRelatedValue2(34);
103: r2c.setRelatedValue3(new Timestamp(TIME));
104: _conn.makePersistent(r2c);
105: while (it.hasNext()) {
106: retval = it.next();
107: ((Contract) retval).setRelatedToContract(r2c);
108: }
109: tx.commit();
110: r2c = null;
111: tx = _kit.getTransaction(_conn);
112: tx.begin();
113: crit = new Criteria();
114: crit.addEqualTo("pk", "E" + TIME);
115: q = QueryFactory.newQuery(Effectiveness.class, crit);
116: it = _conn.getIteratorByQuery(q);
117: retval = null;
118: while (it.hasNext()) {
119: retval = it.next();
120: }
121: tx.commit();
122: assertTrue(
123: "contract object should have a RelatedToContract instance attached",
124: ((Effectiveness) retval).getVersion().getContract()
125: .getRelatedToContract() != null);
126: }
127:
128: public void testSwizzle3() throws TransactionException,
129: LockingException, PBFactoryException,
130: PersistenceBrokerException {
131: clearTestData();
132: TestClassA a = generateTestData();
133: Transaction tx = _kit.getTransaction(_conn);
134: tx.begin();
135: _conn.makePersistent(a.getB());
136: _conn.makePersistent(a);
137: TestClassB b = a.getB();
138: tx.commit();
139: /**
140: * clear to start test
141: */
142: _conn.invalidateAll();
143: tx = _kit.getTransaction(_conn);
144: tx.begin();
145: /**
146: * load B
147: */
148: Identity oidb = _conn.getIdentity(b);
149: TestClassB b1 = (TestClassB) _conn.getObjectByIdentity(oidb);
150: assertTrue(b1 != null);
151: /**
152: * load A
153: */
154: Identity oida = _conn.getIdentity(a);
155: TestClassA a1 = (TestClassA) _conn.getObjectByIdentity(oida);
156:
157: /**
158: * B, as navigated from A, should be the same as B gotten directly.
159: */
160: assertTrue(a1.getB().equals(b1));
161: tx.commit();
162:
163: /**
164: * clear
165: */
166: clearTestData();
167: }
168:
169: private void createTestData() throws TransactionException,
170: LockingException {
171: for (int i = 0; i < COUNT; i++) {
172: Transaction tx = _kit.getTransaction(_conn);
173: tx.begin();
174: Contract contract = new Contract();
175: contract.setPk("C" + TIME);
176: contract.setContractValue1("contractvalue1");
177: contract.setContractValue2(1);
178: contract.setContractValue3("contractvalue3");
179: contract.setContractValue4(new Timestamp(TIME));
180: _conn.makePersistent(contract);
181: tx.commit();
182: tx = _kit.getTransaction(_conn);
183: tx.begin();
184: Version version = new Version();
185: version.setPk("V" + TIME);
186: version.setVersionValue1("versionvalue1");
187: version.setVersionValue2(1);
188: version.setVersionValue3(new Timestamp(TIME));
189: version.setContract(contract);
190: _conn.makePersistent(version);
191: tx.commit();
192: tx = _kit.getTransaction(_conn);
193: tx.begin();
194: Effectiveness eff = new Effectiveness();
195: eff.setPk("E" + TIME);
196: eff.setEffValue1("effvalue1");
197: eff.setEffValue2(1);
198: eff.setEffValue3(new Timestamp(TIME));
199: eff.setVersion(version);
200: _conn.makePersistent(eff);
201: tx.commit();
202: }
203: }
204:
205: public void deleteAllData() throws LockingException {
206: Criteria crit = new Criteria();
207: Query q;
208: Iterator iter;
209: /**
210: * delete effectiveness first
211: */
212: Transaction tx = _kit.getTransaction(_conn);
213: tx.begin();
214: q = QueryFactory.newQuery(Effectiveness.class, crit);
215: iter = _conn.getIteratorByQuery(q);
216: while (iter.hasNext()) {
217: _conn.deletePersistent(iter.next());
218: }
219: tx.commit();
220: /**
221: * then version
222: */
223: tx = _kit.getTransaction(_conn);
224: tx.begin();
225: q = QueryFactory.newQuery(Version.class, crit);
226: iter = _conn.getIteratorByQuery(q);
227: while (iter.hasNext()) {
228: _conn.deletePersistent(iter.next());
229: }
230: tx.commit();
231: /**
232: * the contract
233: */
234: tx = _kit.getTransaction(_conn);
235: tx.begin();
236: q = QueryFactory.newQuery(Contract.class, crit);
237: iter = _conn.getIteratorByQuery(q);
238: while (iter.hasNext()) {
239: _conn.deletePersistent(iter.next());
240: }
241: tx.commit();
242: }
243:
244: public void testSwizzle2() throws TransactionException,
245: LockingException, PBFactoryException,
246: PersistenceBrokerException {
247: clearTestData();
248: TestClassA a = generateTestData();
249: Transaction tx = _kit.getTransaction(_conn);
250: tx.begin();
251: _conn.makePersistent(a.getB());
252: _conn.makePersistent(a);
253: tx.commit();
254: /**
255: * clear to start test
256: */
257: _conn.invalidateAll();
258: /**
259: * get A to make it and the related B in cache
260: */
261: tx = _kit.getTransaction(_conn);
262: tx.begin();
263: Identity oid = _conn.getIdentity(a);
264: TestClassA a1 = (TestClassA) _conn.getObjectByIdentity(oid);
265: assertTrue(a1.getB() != null);
266: assertTrue(a1.getB().getValue1().equals("hi there"));
267: /**
268: * everything is good, update b
269: */
270: tx.commit();
271:
272: /**
273: * now get B and update it, do NOT get it by traversing A
274: */
275: tx = _kit.getTransaction(_conn);
276: tx.begin();
277: Identity boid = _conn.getIdentity(a.getB());
278: TestClassB b1 = (TestClassB) _conn.getObjectByIdentity(boid);
279: assertTrue(b1 != null);
280: assertTrue(b1.getValue1().equals("hi there"));
281: /**
282: * everything is good, update b
283: */
284: _conn.lockForWrite(b1);
285: b1.setValue1("goodbye there");
286: tx.commit();
287: /**
288: * make sure b was updated
289: */
290: tx = _kit.getTransaction(_conn);
291: tx.begin();
292: boid = _conn.getIdentity(a.getB());
293: b1 = (TestClassB) _conn.getObjectByIdentity(boid);
294: assertTrue(b1 != null);
295: assertTrue(b1.getValue1().equals("goodbye there"));
296: tx.commit();
297:
298: /**
299: * now get A again and make sure the related B is updated to reflect
300: * the new value.
301: */
302: tx = _kit.getTransaction(_conn);
303: tx.begin();
304: TestClassA a2 = (TestClassA) _conn.getObjectByIdentity(oid);
305: assertTrue(a2.getB() != null);
306: assertTrue(a2.getB().getValue1().equals("goodbye there"));
307: tx.commit();
308: clearTestData();
309: }
310:
311: public void testSwizzleNto1() throws Exception {
312: clearTestData();
313: TestClassA a = generateTestData();
314: TestClassB b2 = generateAnotherB();
315: Transaction tx = _kit.getTransaction(_conn);
316: tx.begin();
317: _conn.makePersistent(a.getB());
318: _conn.makePersistent(a);
319: tx.commit();
320: /**
321: * change B
322: */
323: tx = _kit.getTransaction(_conn);
324: tx.begin();
325: Identity oid = _conn.getIdentity(a);
326: TestClassA a1 = (TestClassA) _conn.getObjectByIdentity(oid);
327: _conn.makePersistent(b2);
328: a1.setB(b2);
329: tx.commit();
330:
331: tx = _kit.getTransaction(_conn);
332: tx.begin();
333: a = (TestClassA) _conn.getObjectByIdentity(oid);
334: assertTrue(a.getB() != null);
335: assertTrue(a.getB().getValue1().equals("value2"));
336: a.setB(null);
337: tx.commit();
338:
339: tx = _kit.getTransaction(_conn);
340: tx.begin();
341: a = (TestClassA) _conn.getObjectByIdentity(oid);
342: assertTrue(a.getB() == null);
343: tx.commit();
344: }
345:
346: public void testSwizzle1toN() throws Exception {
347: if (ojbSkipKnownIssueProblem("OTM-layer has caching issues")) {
348: return;
349: }
350: clearTestData();
351: Transaction tx = _kit.getTransaction(_conn);
352: tx.begin();
353: ProductGroup pg = new ProductGroup();
354: pg.setId(new Integer(77777));
355: pg.setName("1");
356: _conn.makePersistent(pg);
357: Article article = Article.createInstance();
358: article.setArticleId(new Integer(77777));
359: article.setStock(333);
360: pg.add(article);
361: article.setProductGroup(pg);
362: _conn.makePersistent(article);
363: Identity pgOid = _conn.getIdentity(pg);
364: tx.commit();
365:
366: tx = _kit.getTransaction(_conn);
367: tx.begin();
368: pg = (ProductGroup) _conn.getObjectByIdentity(pgOid);
369: pg.getAllArticlesInGroup().clear();
370: tx.commit();
371:
372: tx = _kit.getTransaction(_conn);
373: tx.begin();
374: pg = (ProductGroup) _conn.getObjectByIdentity(pgOid);
375: assertEquals("should be equal", 0, pg.getAllArticlesInGroup()
376: .size());
377: tx.commit();
378:
379: tx = _kit.getTransaction(_conn);
380: tx.begin();
381: pg = (ProductGroup) _conn.getObjectByIdentity(pgOid);
382: pg.getAllArticlesInGroup().add(article);
383: tx.commit();
384:
385: tx = _kit.getTransaction(_conn);
386: tx.begin();
387: pg = (ProductGroup) _conn.getObjectByIdentity(pgOid);
388: assertEquals("should be equal", 1, pg.getAllArticlesInGroup()
389: .size());
390: tx.commit();
391: clearTestData();
392: }
393:
394: public void testSwizzle4() throws TransactionException,
395: LockingException, PBFactoryException,
396: PersistenceBrokerException {
397: clearTestData();
398: TestClassA a = generateTestData();
399: TestClassB b = a.getB();
400: Transaction tx = _kit.getTransaction(_conn);
401:
402: tx.begin();
403: _conn.makePersistent(b);
404: _conn.makePersistent(a);
405: b.setA(a);
406: tx.commit();
407: /**
408: * clear to start test
409: */
410: _conn.invalidateAll();
411: tx = _kit.getTransaction(_conn);
412: tx.begin();
413: /**
414: * load B
415: */
416: Identity oidb = _conn.getIdentity(b);
417: TestClassB b1 = (TestClassB) _conn.getObjectByIdentity(oidb);
418: /**
419: * load A
420: */
421: Identity oida = _conn.getIdentity(a);
422: TestClassA a1 = (TestClassA) _conn.getObjectByIdentity(oida);
423: assertTrue(a1 != null);
424: assertTrue(a1.getB().equals(b1));
425: assertTrue(b1.getA().equals(a1));
426: /**
427: * update B
428: */
429: a.setValue1("a");
430: _conn.makePersistent(a);
431:
432: /**
433: * B, as navigated from A, should be the same as B gotten directly.
434: */
435: assertTrue(a1.getValue1().equals(a.getValue1()));
436: tx.commit();
437:
438: /**
439: * clear
440: */
441: clearTestData();
442: }
443:
444: /**
445: * Cache data must be independent of any objects available to used,
446: * otherwise modification of user objects outside transaction will
447: * damage cache data
448: */
449: public void testCacheIndependence() throws Throwable {
450: Transaction tx = null;
451: Collection addresses = this .getAddresses();
452: deleteAddresses(addresses);
453: Identity oid;
454: Address address = new Address("oldCountry", "oldCity",
455: "oldStreet");
456:
457: try {
458: tx = _kit.getTransaction(_conn);
459: tx.begin();
460: _conn.makePersistent(address);
461: oid = _conn.getIdentity(address);
462: tx.commit();
463:
464: address.setStreet("newStreet");
465:
466: tx = _kit.getTransaction(_conn);
467: tx.begin();
468: address = (Address) _conn.getObjectByIdentity(oid);
469: assertEquals("Cache was damaged.", "oldStreet", address
470: .getStreet());
471: tx.commit();
472:
473: address.setStreet("newStreet");
474:
475: tx = _kit.getTransaction(_conn);
476: tx.begin();
477: address = (Address) _conn.getObjectByIdentity(oid,
478: LockType.WRITE_LOCK);
479: assertEquals("Cache was damaged.", "oldStreet", address
480: .getStreet());
481: tx.commit();
482:
483: address.setStreet("newStreet");
484:
485: tx = _kit.getTransaction(_conn);
486: tx.begin();
487: address = (Address) _conn.getObjectByIdentity(oid);
488: assertEquals("Cache was damaged.", "oldStreet", address
489: .getStreet());
490: tx.commit();
491: } catch (Throwable e) {
492: if (tx != null) {
493: try {
494: tx.rollback();
495: } catch (Throwable ex) {
496: ex.printStackTrace();
497: }
498: }
499: throw e;
500: }
501: }
502:
503: public void testSomethingSimple() throws Throwable {
504: Collection addresses = this .getAddresses();
505: addresses = deleteAddresses(addresses);
506:
507: addresses
508: .add(new Address("oldCountry", "oldCity", "oldStreet"));
509:
510: addresses = this .updateAddresses(addresses);
511:
512: Iterator iter = addresses.iterator();
513: while (iter.hasNext()) {
514: Address address = (Address) iter.next();
515: address.setStreet("newStreet");
516: }
517: addresses = this .updateAddresses(addresses);
518: addresses = this .getAddresses();
519: assertEquals("Collection of addresses must be 1. ", 1,
520: addresses.size());
521: iter = addresses.iterator();
522: while (iter.hasNext()) {
523: Address address = (Address) iter.next();
524: assertEquals("New street not set.", "newStreet", address
525: .getStreet());
526: }
527: }
528:
529: private Collection getAddresses() throws Throwable {
530: Transaction tx = null;
531: Collection addresses;
532: try {
533: tx = _kit.getTransaction(_conn);
534: tx.begin();
535: _conn.invalidateAll();
536: Query q = QueryFactory.newQuery(Address.class,
537: (Criteria) null);
538: addresses = _conn.getCollectionByQuery(q);
539: tx.commit();
540: } catch (Throwable e) {
541: if (tx != null) {
542: try {
543: tx.rollback();
544: } catch (Throwable ex) {
545: ex.printStackTrace();
546: }
547: }
548: throw e;
549: }
550: return addresses;
551: }
552:
553: private Collection updateAddresses(Collection newAddresses)
554: throws Throwable {
555: Transaction tx = null;
556: Collection oldAddresses;
557: try {
558: tx = _kit.getTransaction(_conn);
559: tx.begin();
560:
561: Query q = QueryFactory.newQuery(Address.class,
562: (Criteria) null);
563: oldAddresses = _conn.getCollectionByQuery(q);
564:
565: Iterator oldAddressesIterator = oldAddresses.iterator();
566: while (oldAddressesIterator.hasNext()) {
567: Address oldAddress = (Address) oldAddressesIterator
568: .next();
569: if (!newAddresses.contains(oldAddress)) {
570: _conn.deletePersistent(oldAddress);
571: }
572: }
573:
574: Iterator newAddressesIterator = newAddresses.iterator();
575: while (newAddressesIterator.hasNext()) {
576: Address newAddress = (Address) newAddressesIterator
577: .next();
578: _conn.makePersistent(newAddress);
579: }
580: tx.commit();
581: } catch (Throwable e) {
582: if (tx != null) {
583: try {
584: tx.rollback();
585: } catch (Throwable ex) {
586: ex.printStackTrace();
587: }
588: }
589: throw e;
590: }
591: return newAddresses;
592: }
593:
594: private Collection deleteAddresses(Collection oldAddresses)
595: throws Throwable {
596: Transaction tx = null;
597: try {
598: tx = _kit.getTransaction(_conn);
599: tx.begin();
600:
601: Iterator oldAddressesIterator = oldAddresses.iterator();
602: while (oldAddressesIterator.hasNext()) {
603: Address oldAddress = (Address) oldAddressesIterator
604: .next();
605: _conn.deletePersistent(oldAddress);
606: oldAddressesIterator.remove();
607: }
608: tx.commit();
609: } catch (Throwable e) {
610: if (tx != null) {
611: try {
612: tx.rollback();
613: } catch (Throwable ex) {
614: ex.printStackTrace();
615: }
616: }
617: throw e;
618: }
619: return oldAddresses;
620: }
621:
622: private void clearTestData() throws LockingException {
623: TestClassA a = generateTestData();
624: TestClassB b2 = generateAnotherB();
625: Transaction tx = _kit.getTransaction(_conn);
626: tx.begin();
627: Identity oid = _conn.getIdentity(a);
628: Identity oidb = _conn.getIdentity(a.getB());
629: Identity oidb2 = _conn.getIdentity(b2);
630: TestClassA a1 = (TestClassA) _conn.getObjectByIdentity(oid);
631: if (a1 != null) {
632: _conn.deletePersistent(a1);
633: }
634: TestClassB b1 = (TestClassB) _conn.getObjectByIdentity(oidb);
635: if (b1 != null) {
636: _conn.deletePersistent(b1);
637: }
638: b2 = (TestClassB) _conn.getObjectByIdentity(oidb2);
639: if (b2 != null) {
640: _conn.deletePersistent(b2);
641: }
642:
643: Article article = Article.createInstance();
644: article.setArticleId(new Integer(77777));
645: ProductGroup pg = new ProductGroup();
646: pg.setId(new Integer(77777));
647: Identity oidArt = _conn.getIdentity(article);
648: Identity oidPG = _conn.getIdentity(pg);
649: article = (Article) _conn.getObjectByIdentity(oidArt);
650: if (article != null) {
651: _conn.deletePersistent(article);
652: }
653: pg = (ProductGroup) _conn.getObjectByIdentity(oidPG);
654: if (pg != null) {
655: _conn.deletePersistent(pg);
656: }
657: tx.commit();
658: }
659:
660: private TestClassA generateTestData() {
661: TestClassA tca = new TestClassA();
662: tca.setOid("someoid");
663: tca.setValue1("abc");
664: tca.setValue2("123");
665: tca.setValue3(5);
666: TestClassB tcb = new TestClassB();
667: tcb.setOid("boid");
668: tcb.setValue1("hi there");
669: tca.setB(tcb);
670: return tca;
671: }
672:
673: private TestClassB generateAnotherB() {
674: TestClassB tcb = new TestClassB();
675: tcb.setOid("boid2");
676: tcb.setValue1("value2");
677: return tcb;
678: }
679: }
|