0001: package org.apache.ojb.odmg;
0002:
0003: import java.util.ArrayList;
0004: import java.util.Collection;
0005: import java.util.Iterator;
0006: import java.util.LinkedList;
0007: import java.util.List;
0008:
0009: import org.apache.commons.lang.StringUtils;
0010: import org.apache.commons.lang.builder.EqualsBuilder;
0011: import org.apache.commons.lang.builder.ToStringBuilder;
0012: import org.apache.ojb.broker.ManageableCollection;
0013: import org.apache.ojb.broker.PersistenceBroker;
0014: import org.apache.ojb.broker.PersistenceBrokerException;
0015: import org.apache.ojb.broker.OJBRuntimeException;
0016: import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
0017: import org.apache.ojb.broker.query.Criteria;
0018: import org.apache.ojb.broker.query.Query;
0019: import org.apache.ojb.broker.query.QueryFactory;
0020: import org.apache.ojb.junit.ODMGTestCase;
0021: import org.odmg.OQLQuery;
0022: import org.odmg.QueryException;
0023: import org.odmg.Transaction;
0024:
0025: /**
0026: * Test m:n relation handling with the odmg-api. The mandatory auto-update/auto-delete
0027: * setting are 'false' in that case equals to 'LINK'.
0028: * <p/>
0029: * TODO: we need more tests doing delete/update operations on M:N relations
0030: *
0031: * @author <a href="mailto:arminw@apache.org">Armin Waibel</a>
0032: * @version $Id: M2NTest.java,v 1.3.2.6 2005/06/04 17:35:19 arminw Exp $
0033: */
0034: public class M2NTest extends ODMGTestCase {
0035: static final int NONE = ObjectReferenceDescriptor.CASCADE_NONE;
0036: static final int LINK = ObjectReferenceDescriptor.CASCADE_LINK;
0037: static final int OBJECT = ObjectReferenceDescriptor.CASCADE_OBJECT;
0038: boolean oldImpliciteWriteLock;
0039:
0040: public static void main(String[] args) {
0041: junit.textui.TestRunner.main(new String[] { M2NTest.class
0042: .getName() });
0043: }
0044:
0045: protected void setUp() throws Exception {
0046: super .setUp();
0047: oldImpliciteWriteLock = odmg.isImpliciteWriteLocks();
0048: }
0049:
0050: protected void tearDown() throws Exception {
0051: odmg.setImpliciteWriteLocks(oldImpliciteWriteLock);
0052: super .tearDown();
0053: }
0054:
0055: public void testOnetoNViaIndirectionTable() throws Exception {
0056: String name = "testOnetoNViaIndirectionTable_"
0057: + System.currentTimeMillis();
0058: int opId = (int) (Math.random() * Integer.MAX_VALUE);
0059: String cId = "m2n_" + opId;
0060:
0061: // explicit set false
0062: odmg.setImpliciteWriteLocks(false);
0063:
0064: // Make a profile and County
0065: TransactionExt tx = (TransactionExt) odmg.newTransaction();
0066: tx.begin();
0067: OfficeProfile profile = new OfficeProfileImpl();
0068: profile.setId(opId);
0069: County c = new County();
0070: c.setName(name);
0071: c.setId(cId);
0072: odmg.getDatabase(null).makePersistent(profile);
0073: odmg.getDatabase(null).makePersistent(c);
0074: tx.commit();
0075:
0076: tx.begin();
0077: PersistenceBroker pb = tx.getBroker();
0078: pb.clearCache();
0079: // use PB-api to lookup object
0080: Criteria crit = new Criteria();
0081: crit.addLike("name", name);
0082: Query q = QueryFactory.newQuery(County.class, crit);
0083: County county = (County) pb.getObjectByQuery(q);
0084: tx.commit();
0085:
0086: // Add a county to it
0087: tx = (TransactionExt) odmg.newTransaction();
0088: tx.begin();
0089: tx.lock(profile, Transaction.WRITE);
0090: tx.lock(county, Transaction.READ);
0091: // add already persisted County object
0092: profile.addCounty(county);
0093: // add a new County object
0094: County c2 = new County();
0095: c2.setId(cId + "_new");
0096: c2.setName(name + "_new");
0097: profile.addCounty(c2);
0098: tx.commit();
0099:
0100: tx.begin();
0101: OQLQuery query = odmg.newOQLQuery();
0102: query.create("select all from " + OfficeProfile.class.getName()
0103: + " where id=$1");
0104: query.bind(new Integer(opId));
0105: List result = (List) query.execute();
0106: assertEquals(1, result.size());
0107: tx.commit();
0108: OfficeProfile newProfile = (OfficeProfile) result.get(0);
0109: assertTrue(profile.equals(newProfile));
0110:
0111: tx.begin();
0112: tx.lock(newProfile, Transaction.WRITE);
0113: List counties = newProfile.getCounties();
0114: for (int i = 0; i < counties.size(); i++) {
0115: County tmp = (County) counties.get(i);
0116: tmp.setName(tmp.getName() + "_updated");
0117: }
0118: tx.commit();
0119:
0120: tx.begin();
0121: query = odmg.newOQLQuery();
0122: query.create("select all from " + County.class.getName()
0123: + " where name like $1");
0124: query.bind(name + "%");
0125: result = (List) query.execute();
0126: assertEquals(2, result.size());
0127: tx.commit();
0128: for (int i = 0; i < counties.size(); i++) {
0129: County tmp = (County) counties.get(i);
0130: assertTrue(StringUtils.contains(tmp.getName(), "_updated"));
0131: }
0132:
0133: tx.begin();
0134: tx.lock(newProfile, Transaction.WRITE);
0135: counties = newProfile.getCounties();
0136: // this only remove the indirection table entry
0137: County removed = (County) counties.remove(0);
0138: // update the "unlinked" object
0139: removed.setName(removed.getName() + "_unlinked");
0140: tx.commit();
0141:
0142: tx.begin();
0143: query = odmg.newOQLQuery();
0144: query.create("select all from " + County.class.getName()
0145: + " where name=$1");
0146: query.bind(removed.getName());
0147: result = (List) query.execute();
0148: assertEquals(1, result.size());
0149: tx.commit();
0150:
0151: tx.begin();
0152: tx.setCascadingDelete(OfficeProfileImpl.class, true);
0153: database.deletePersistent(newProfile);
0154: tx.commit();
0155:
0156: tx.begin();
0157: query = odmg.newOQLQuery();
0158: query.create("select all from " + County.class.getName()
0159: + " where name like $1");
0160: query.bind(name + "%");
0161: result = (List) query.execute();
0162: // expect to find the unlinked County object
0163: assertEquals(1, result.size());
0164: tx.commit();
0165: }
0166:
0167: public void testTwoMtoNRelationsInOneClass() throws Exception {
0168: String postfixId = "testTwoMtoNRelationsInOneClass_"
0169: + System.currentTimeMillis();
0170: Movie m = new MovieImpl(postfixId, "Movie_" + postfixId, "none");
0171:
0172: Actor a1 = new Actor("Actor_1_" + postfixId);
0173: m.addActors(a1);
0174:
0175: Actor a2a = new Actor("Actor_2a_" + postfixId);
0176: m.addActors2(a2a);
0177: Actor a2b = new Actor("Actor_2b_" + postfixId);
0178: m.addActors2(a2b);
0179:
0180: TransactionExt tx = (TransactionExt) odmg.newTransaction();
0181: tx.begin();
0182: database.makePersistent(m);
0183: tx.commit();
0184:
0185: tx.begin();
0186: tx.getBroker().clearCache();
0187:
0188: OQLQuery queryMovie = movieQuery(postfixId);
0189: Collection resultMovie = (Collection) queryMovie.execute();
0190: assertEquals(1, resultMovie.size());
0191: Movie newMovie = (Movie) resultMovie.iterator().next();
0192: assertNotNull(newMovie.getActors());
0193: assertEquals(1, newMovie.getActors().size());
0194: assertEquals(2, newMovie.getActors2().size());
0195:
0196: OQLQuery queryActor = actorQuery(postfixId);
0197: Collection resultActor = (Collection) queryActor.execute();
0198: assertEquals(1 + 2, resultActor.size());
0199:
0200: OQLQuery queryRole = roleQuery(null, m);
0201: Collection resultRole = (Collection) queryRole.execute();
0202: assertEquals(1, resultRole.size());
0203:
0204: // remove both Actors from relation and delete one Actor
0205: // instance completely, the other Actor should still in DB
0206: Object removed1 = newMovie.getActors2().remove(0);
0207: Actor removed2 = (Actor) newMovie.getActors2().remove(0);
0208: database.deletePersistent(removed1);
0209: // update the Actor unlinked from relation
0210: tx.lock(removed2, Transaction.WRITE);
0211: String newName = removed2.getName() + "_updated";
0212: removed2.setName(newName);
0213: tx.commit();
0214:
0215: queryMovie = movieQuery(postfixId);
0216: resultMovie = (Collection) queryMovie.execute();
0217: assertEquals(1, resultMovie.size());
0218: newMovie = (Movie) resultMovie.iterator().next();
0219: assertNotNull(newMovie.getActors());
0220: assertEquals(1, newMovie.getActors().size());
0221: assertEquals(0, newMovie.getActors2().size());
0222:
0223: queryActor = actorQuery(postfixId);
0224: resultActor = (Collection) queryActor.execute();
0225: assertEquals(1 + 1, resultActor.size());
0226:
0227: queryActor = actorQuery(newName);
0228: resultActor = (Collection) queryActor.execute();
0229: assertEquals(1, resultActor.size());
0230:
0231: queryRole = roleQuery(null, m);
0232: resultRole = (Collection) queryRole.execute();
0233: assertEquals(1, resultRole.size());
0234: }
0235:
0236: public void testStore() throws Exception {
0237: // arminw: fixed
0238: // TODO: Seems that the order of objects is not valid to insert M:N
0239: //if(ojbSkipKnownIssueProblem()) return;
0240: changeMovieCollectionDescriptorTo(true, NONE, NONE, false);
0241: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0242: doTestStore();
0243: }
0244:
0245: public void testStoreWithProxy() throws Exception {
0246: // arminw: fixed
0247: // TODO: Seems that the order of objects is not valid to insert M:N
0248: // if(ojbSkipKnownIssueProblem()) return;
0249: changeMovieCollectionDescriptorTo(true, NONE, NONE, true);
0250: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0251: doTestStore();
0252: }
0253:
0254: public void doTestStore() throws Exception {
0255: String postfix = "doTestStore_" + System.currentTimeMillis();
0256: Movie movie = buildMovieWithActors(postfix);
0257:
0258: Transaction tx = odmg.newTransaction();
0259: tx.begin();
0260: database.makePersistent(movie);
0261: tx.commit();
0262:
0263: OQLQuery queryMovie = movieQuery(postfix);
0264: Collection resultMovie = (Collection) queryMovie.execute();
0265: assertEquals(1, resultMovie.size());
0266: Movie newMovie = (Movie) resultMovie.iterator().next();
0267: assertNotNull(newMovie.getActors());
0268: assertEquals(3, newMovie.getActors().size());
0269: assertEquals(2, newMovie.getActors2().size());
0270:
0271: OQLQuery queryActor = actorQuery(postfix);
0272: Collection resultActor = (Collection) queryActor.execute();
0273: assertEquals(3 + 2, resultActor.size());
0274:
0275: OQLQuery queryRole = roleQuery(null, movie);
0276: Collection resultRole = (Collection) queryRole.execute();
0277: assertEquals(3, resultRole.size());
0278: }
0279:
0280: public void testStore_2() throws Exception {
0281: changeMovieCollectionDescriptorTo(true, NONE, NONE, false);
0282: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0283: doTestStore_2();
0284: }
0285:
0286: // arminw: this test will not work, because we use a user defined ManageableCollection
0287: // and the collection proxy is not compatible. Maybe this test will work in future versions
0288: // when it's possible set a CollectionProxy impl in metadate.
0289: // public void testStore_2WithProxy() throws Exception
0290: // {
0291: // prepareAutoUpdateDeleteSettings(true);
0292: // doTestStore_2();
0293: // }
0294:
0295: public void doTestStore_2() throws Exception {
0296: String postfix = "doTestStore_2_" + System.currentTimeMillis();
0297: Movie movie = buildMovieWithActors(postfix);
0298:
0299: Transaction tx = odmg.newTransaction();
0300: tx.begin();
0301: Iterator it = movie.getActors().iterator();
0302: while (it.hasNext()) {
0303: database.makePersistent(it.next());
0304: }
0305: database.makePersistent(movie);
0306: tx.commit();
0307:
0308: OQLQuery queryMovie = movieQuery(postfix);
0309: Collection resultMovie = (Collection) queryMovie.execute();
0310: assertEquals(1, resultMovie.size());
0311: Movie newMovie = (Movie) resultMovie.iterator().next();
0312: assertNotNull(newMovie.getActors());
0313: assertEquals(3, newMovie.getActors().size());
0314:
0315: OQLQuery queryActor = actorQuery(postfix);
0316: Collection resultActor = (Collection) queryActor.execute();
0317: assertEquals(5, resultActor.size());
0318:
0319: OQLQuery queryRole = roleQuery(null, movie);
0320: Collection resultRole = (Collection) queryRole.execute();
0321: assertEquals(3, resultRole.size());
0322: }
0323:
0324: public void testStoreComplex() throws Exception {
0325: // arminw: fixed
0326: // TODO: Seems that the order of objects is not valid to insert M:N
0327: // if(ojbSkipKnownIssueProblem()) return;
0328: changeMovieCollectionDescriptorTo(true, NONE, NONE, false);
0329: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0330: doTestStoreComplex();
0331: }
0332:
0333: public void testStoreComplexWithProxy() throws Exception {
0334: // arminw: fixed
0335: // TODO: Seems that the order of objects is not valid to insert M:N
0336: // if(ojbSkipKnownIssueProblem()) return;
0337: changeMovieCollectionDescriptorTo(true, NONE, NONE, true);
0338: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0339: doTestStoreComplex();
0340: }
0341:
0342: public void doTestStoreComplex() throws Exception {
0343: String postfix = "doTestStoreComplex_"
0344: + System.currentTimeMillis();
0345: Movie movie = buildMovieWithActorsAndBackReferences(postfix);
0346:
0347: Transaction tx = odmg.newTransaction();
0348: tx.begin();
0349: database.makePersistent(movie);
0350: tx.commit();
0351:
0352: OQLQuery queryMovie = movieQuery(postfix);
0353: Collection resultMovie = (Collection) queryMovie.execute();
0354: assertEquals(3, resultMovie.size());
0355: Iterator it = resultMovie.iterator();
0356: boolean matchActors = false;
0357: while (it.hasNext()) {
0358: Movie m = (Movie) it.next();
0359: if (m.getActors() != null) {
0360: matchActors = m.getActors().size() == 3;
0361: if (matchActors)
0362: break;
0363: }
0364: }
0365: assertTrue(matchActors);
0366:
0367: OQLQuery queryActor = actorQuery(postfix);
0368: Collection resultActor = (Collection) queryActor.execute();
0369: assertEquals(3, resultActor.size());
0370: it = resultActor.iterator();
0371: boolean matchMovies = false;
0372: while (it.hasNext()) {
0373: Actor a = (Actor) it.next();
0374: if (a.getMovies() != null) {
0375: matchMovies = a.getMovies().size() == 3;
0376: if (matchMovies)
0377: break;
0378: }
0379: }
0380: assertTrue(matchMovies);
0381:
0382: OQLQuery queryRole = odmg.newOQLQuery();
0383: queryRole.create("select obj from " + Role.class.getName()
0384: + " where movieStrId=$3");
0385: queryRole.bind(postfix);
0386: Collection resultRole = (Collection) queryRole.execute();
0387: assertEquals(5, resultRole.size());
0388: }
0389:
0390: public void testStoreComplex_2() throws Exception {
0391: // arminw: fixed
0392: // TODO: Seems that the order of objects is not valid to insert M:N
0393: // if(ojbSkipKnownIssueProblem()) return;
0394: changeMovieCollectionDescriptorTo(true, NONE, NONE, false);
0395: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0396: doTestStoreComplex_2();
0397: }
0398:
0399: public void testStoreComplex_2_WithProxy() throws Exception {
0400: // arminw: fixed
0401: // TODO: Seems that the order of objects is not valid to insert M:N
0402: // if(ojbSkipKnownIssueProblem()) return;
0403: changeMovieCollectionDescriptorTo(true, NONE, NONE, true);
0404: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0405: doTestStoreComplex_2();
0406: }
0407:
0408: public void doTestStoreComplex_2() throws Exception {
0409: String postfix = "doTestStoreComplex_2_"
0410: + System.currentTimeMillis();
0411: Movie movie = buildMovieWithActorsAndBackReferences(postfix);
0412:
0413: Transaction tx = odmg.newTransaction();
0414: tx.begin();
0415: Iterator it = movie.getActors().iterator();
0416: while (it.hasNext()) {
0417: database.makePersistent(it.next());
0418: }
0419: database.makePersistent(movie);
0420: tx.commit();
0421:
0422: OQLQuery queryMovie = movieQuery(postfix);
0423: Collection resultMovie = (Collection) queryMovie.execute();
0424: assertEquals(3, resultMovie.size());
0425: it = resultMovie.iterator();
0426: boolean matchActors = false;
0427: while (it.hasNext()) {
0428: Movie m = (Movie) it.next();
0429: if (m.getActors() != null) {
0430: matchActors = m.getActors().size() == 3;
0431: if (matchActors)
0432: break;
0433: }
0434: }
0435:
0436: OQLQuery queryActor = actorQuery(postfix);
0437: Collection resultActor = (Collection) queryActor.execute();
0438: assertEquals(3, resultActor.size());
0439: it = resultActor.iterator();
0440: boolean matchMovies = false;
0441: while (it.hasNext()) {
0442: Actor a = (Actor) it.next();
0443: if (a.getMovies() != null) {
0444: matchMovies = a.getMovies().size() == 3;
0445: if (matchMovies)
0446: break;
0447: }
0448: }
0449: assertTrue(matchMovies);
0450:
0451: OQLQuery queryRole = odmg.newOQLQuery();
0452: queryRole.create("select obj from " + Role.class.getName()
0453: + " where movieStrId=$3");
0454: queryRole.bind(postfix);
0455: Collection resultRole = (Collection) queryRole.execute();
0456: assertEquals(5, resultRole.size());
0457: }
0458:
0459: public void testStoreDelete() throws Exception {
0460: changeMovieCollectionDescriptorTo(true, NONE, NONE, false);
0461: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0462: doTestStoreDelete();
0463: }
0464:
0465: public void testStoreDeleteWithProxy() throws Exception {
0466: changeMovieCollectionDescriptorTo(true, NONE, NONE, true);
0467: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0468: doTestStoreDelete();
0469: }
0470:
0471: public void doTestStoreDelete() throws Exception {
0472: String postfix = "doTestStoreDelete_"
0473: + System.currentTimeMillis();
0474: Movie movie = buildMovieWithActors(postfix);
0475:
0476: TransactionExt tx = (TransactionExt) odmg.newTransaction();
0477: tx.begin();
0478: Iterator it = movie.getActors().iterator();
0479: while (it.hasNext()) {
0480: database.makePersistent(it.next());
0481: }
0482: database.makePersistent(movie);
0483: tx.commit();
0484:
0485: OQLQuery queryMovie = movieQuery(postfix);
0486: Collection resultMovie = (Collection) queryMovie.execute();
0487: assertEquals(1, resultMovie.size());
0488: Movie newMovie = (Movie) resultMovie.iterator().next();
0489: assertNotNull(newMovie.getActors());
0490: assertEquals(3, newMovie.getActors().size());
0491:
0492: OQLQuery queryActor = actorQuery(postfix);
0493: Collection resultActor = (Collection) queryActor.execute();
0494: assertEquals(5, resultActor.size());
0495:
0496: OQLQuery queryRole = roleQuery(null, movie);
0497: Collection resultRole = (Collection) queryRole.execute();
0498: assertEquals(3, resultRole.size());
0499:
0500: tx.begin();
0501: tx.getBroker().clearCache();
0502: queryMovie = movieQuery(postfix);
0503: resultMovie = (Collection) queryMovie.execute();
0504: Movie m = (Movie) resultMovie.iterator().next();
0505: assertNotNull(m);
0506: //**********************************************
0507: tx.lock(m, Transaction.WRITE);
0508: it = m.getActors().iterator();
0509: Actor actor = (Actor) it.next();
0510: /*
0511: we expect that the entry in indirection table was removed
0512: AND the Actor object itself will be deleted
0513: */
0514: database.deletePersistent(actor);
0515: //*********************************************
0516: tx.commit();
0517:
0518: tx.begin();
0519: tx.getBroker().clearCache();
0520: //tx.commit();
0521:
0522: queryMovie = movieQuery(postfix);
0523: resultMovie = (Collection) queryMovie.execute();
0524: assertEquals(1, resultMovie.size());
0525: newMovie = (Movie) resultMovie.iterator().next();
0526: assertNotNull(newMovie.getActors());
0527: assertEquals(2, newMovie.getActors().size());
0528:
0529: queryActor = actorQuery(postfix);
0530: resultActor = (Collection) queryActor.execute();
0531: assertEquals(4, resultActor.size());
0532:
0533: queryRole = roleQuery(null, movie);
0534: resultRole = (Collection) queryRole.execute();
0535: assertEquals(2, resultRole.size());
0536:
0537: tx.commit();
0538: }
0539:
0540: /**
0541: * Use auto-delete="object" to enable cascading delete.
0542: */
0543: public void testStoreDeleteCascade() throws Exception {
0544: String postfix = "doTestStoreDeleteCascade_"
0545: + System.currentTimeMillis();
0546:
0547: changeMovieCollectionDescriptorTo(true, NONE, OBJECT, true);
0548: changeActorCollectionDescriptorTo(true, NONE, OBJECT, false);
0549:
0550: Movie movie = buildMovieWithActors(postfix);
0551:
0552: TransactionExt tx = (TransactionExt) odmg.newTransaction();
0553: tx.begin();
0554: database.makePersistent(movie);
0555: tx.commit();
0556:
0557: OQLQuery queryMovie = movieQuery(postfix);
0558: Collection resultMovie = (Collection) queryMovie.execute();
0559: assertEquals(1, resultMovie.size());
0560: Movie newMovie = (Movie) resultMovie.iterator().next();
0561: assertNotNull(newMovie.getActors());
0562: assertEquals(3, newMovie.getActors().size());
0563:
0564: OQLQuery queryActor = actorQuery(postfix);
0565: Collection resultActor = (Collection) queryActor.execute();
0566: assertEquals(5, resultActor.size());
0567:
0568: OQLQuery queryRole = roleQuery(null, movie);
0569: Collection resultRole = (Collection) queryRole.execute();
0570: assertEquals(3, resultRole.size());
0571:
0572: tx.begin();
0573: tx.getBroker().clearCache();
0574: queryMovie = movieQuery(postfix);
0575: resultMovie = (Collection) queryMovie.execute();
0576: Movie m = (Movie) resultMovie.iterator().next();
0577: //**********************************************
0578: database.deletePersistent(m);
0579: //*********************************************
0580: tx.commit();
0581:
0582: tx.begin();
0583: tx.getBroker().clearCache();
0584:
0585: queryMovie = movieQuery(postfix);
0586: resultMovie = (Collection) queryMovie.execute();
0587: assertEquals(0, resultMovie.size());
0588:
0589: queryActor = actorQuery(postfix);
0590: resultActor = (Collection) queryActor.execute();
0591: assertEquals(0, resultActor.size());
0592:
0593: queryRole = roleQuery(null, movie);
0594: resultRole = (Collection) queryRole.execute();
0595: assertEquals(0, resultRole.size());
0596:
0597: tx.commit();
0598: }
0599:
0600: public void testRemoveAssociation() throws Exception {
0601: changeMovieCollectionDescriptorTo(true, NONE, NONE, false);
0602: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0603: doTestRemoveAssociation();
0604: }
0605:
0606: public void testRemoveAssociationWithProxy() throws Exception {
0607: changeMovieCollectionDescriptorTo(true, NONE, NONE, true);
0608: changeActorCollectionDescriptorTo(true, NONE, NONE, false);
0609: doTestRemoveAssociation();
0610: }
0611:
0612: public void doTestRemoveAssociation() throws Exception {
0613: String postfix = "doTestRemoveAssociation_"
0614: + System.currentTimeMillis();
0615: Movie movie = buildMovieWithActors(postfix);
0616:
0617: TransactionExt tx = (TransactionExt) odmg.newTransaction();
0618: tx.begin();
0619: Iterator it = movie.getActors().iterator();
0620: while (it.hasNext()) {
0621: database.makePersistent(it.next());
0622: }
0623: database.makePersistent(movie);
0624: tx.commit();
0625:
0626: OQLQuery queryMovie = movieQuery(postfix);
0627: Collection resultMovie = (Collection) queryMovie.execute();
0628: assertEquals(1, resultMovie.size());
0629: Movie newMovie = (Movie) resultMovie.iterator().next();
0630: assertNotNull(newMovie.getActors());
0631: assertEquals(3, newMovie.getActors().size());
0632:
0633: OQLQuery queryActor = actorQuery(postfix);
0634: Collection resultActor = (Collection) queryActor.execute();
0635: assertEquals(5, resultActor.size());
0636:
0637: OQLQuery queryRole = roleQuery(null, movie);
0638: Collection resultRole = (Collection) queryRole.execute();
0639: assertEquals(3, resultRole.size());
0640:
0641: tx.begin();
0642: tx.getBroker().clearCache();
0643:
0644: queryMovie = movieQuery(postfix);
0645: resultMovie = (Collection) queryMovie.execute();
0646: assertEquals(1, resultMovie.size());
0647: Movie m = (Movie) resultMovie.iterator().next();
0648: assertNotNull(m);
0649: Collection actors = m.getActors();
0650: assertEquals(3, actors.size());
0651: //***************************************
0652: tx.lock(m, Transaction.WRITE);
0653: /*
0654: now remove an association between Movie ans Actor
0655: we expect that the entry in indirection class will be removed,
0656: but the Actor entry should be still there
0657: */
0658: Iterator iter = actors.iterator();
0659: iter.next();
0660: iter.remove();
0661: //***************************************
0662: assertEquals(2, m.getActors().size());
0663: tx.commit();
0664:
0665: tx.begin();
0666: tx.getBroker().clearCache();
0667: //tx.commit();
0668:
0669: queryMovie = movieQuery(postfix);
0670: resultMovie = (Collection) queryMovie.execute();
0671: assertEquals(1, resultMovie.size());
0672: newMovie = (Movie) resultMovie.iterator().next();
0673: assertNotNull(newMovie.getActors());
0674: assertEquals(2, newMovie.getActors().size());
0675:
0676: queryRole = roleQuery(null, movie);
0677: resultRole = (Collection) queryRole.execute();
0678: assertEquals(2, resultRole.size());
0679:
0680: // we only remove the association
0681: queryActor = actorQuery(postfix);
0682: resultActor = (Collection) queryActor.execute();
0683: assertEquals(5, resultActor.size());
0684:
0685: tx.commit();
0686: }
0687:
0688: //=======================================================================
0689: // helper methods
0690: //=======================================================================
0691:
0692: OQLQuery movieQuery(String postfix) throws QueryException {
0693: OQLQuery query = odmg.newOQLQuery();
0694: query.create("select obj from " + Movie.class.getName()
0695: + " where idStr like $1");
0696: query.bind("%" + postfix + "%");
0697: return query;
0698: }
0699:
0700: OQLQuery actorQuery(String postfix) throws QueryException {
0701: OQLQuery query = odmg.newOQLQuery();
0702: query.create("select obj from " + Actor.class.getName()
0703: + " where name like $1");
0704: query.bind("%" + postfix + "%");
0705: return query;
0706: }
0707:
0708: OQLQuery roleQuery(Actor actor, Movie movie) throws QueryException {
0709: OQLQuery query = odmg.newOQLQuery();
0710: String select = "select obj from " + Role.class.getName()
0711: + " where";
0712: boolean needsAnd = false;
0713: if (actor != null) {
0714: select = select + " actorId=$1 and actorId2=$2";
0715: needsAnd = true;
0716: }
0717: if (movie != null) {
0718: if (needsAnd)
0719: select = select + " and";
0720: select = select
0721: + " movieIntId=$3 and movieIntId2=$4 and movieStrId=$5";
0722: }
0723: query.create(select);
0724: if (actor != null) {
0725: query.bind(actor.getId());
0726: query.bind(actor.getId2());
0727:
0728: }
0729: if (movie != null) {
0730: query.bind(movie.getIdInt());
0731: query.bind(movie.getIdInt2());
0732: query.bind(movie.getIdStr());
0733: }
0734: return query;
0735: }
0736:
0737: /**
0738: * Returns 1 movie object with 3 actor objects in actors-collection
0739: * and 2 actor objects in actors2-collection
0740: */
0741: Movie buildMovieWithActors(String postfixId) {
0742: Movie m = new MovieImpl(
0743: postfixId,
0744: "Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb "
0745: + postfixId,
0746: "An insane general starts a process to nuclear holocaust that a war"
0747: + " room of politicians and generals frantically try to stop. "
0748: + postfixId);
0749:
0750: Actor a1 = new Actor("Peter Sellers " + postfixId);
0751: Actor a2 = new Actor("George C. Scott " + postfixId);
0752: Actor a3 = new Actor("Sterling Hayden " + postfixId);
0753: ArrayList list = new ArrayList();
0754: list.add(a1);
0755: list.add(a2);
0756: list.add(a3);
0757: m.setActors(list);
0758:
0759: Actor a4 = new Actor("Actor 2 A " + postfixId);
0760: Actor a5 = new Actor("Actor 2 B " + postfixId);
0761: ArrayList list2 = new ArrayList();
0762: list2.add(a4);
0763: list2.add(a5);
0764: m.setActors2(list2);
0765:
0766: return m;
0767: }
0768:
0769: /**
0770: * Returns 1 movie object m1 with 3 actor objects and one actor object with
0771: * back-reference to movie object m1 + 2 new movies
0772: */
0773: Movie buildMovieWithActorsAndBackReferences(String postfixId) {
0774: Movie m = new MovieImpl(
0775: postfixId,
0776: "Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb "
0777: + postfixId,
0778: "An insane general starts a process to nuclear holocaust that a war"
0779: + " room of politicians and generals frantically try to stop. "
0780: + postfixId);
0781: Actor a1 = new Actor("Peter Sellers " + postfixId);
0782: Actor a2 = new Actor("George C. Scott " + postfixId);
0783: Actor a3 = new Actor("Sterling Hayden " + postfixId);
0784: ArrayList list = new ArrayList();
0785: list.add(a1);
0786: list.add(a2);
0787: list.add(a3);
0788: m.setActors(list);
0789:
0790: Movie m1 = new MovieImpl(postfixId + "", "A Shot in the Dark",
0791: "As murder follows murder, beautiful Maria is the obvious suspect...");
0792: Movie m2 = new MovieImpl(
0793: postfixId + "",
0794: "The Pink Panther",
0795: " In the first movie starring Peter Sellers as the bumbling Inspector Clouseau...");
0796:
0797: MovieManageableCollection mlist1 = new MovieManageableCollectionImpl();
0798: mlist1.add(m);
0799: mlist1.add(m1);
0800: mlist1.add(m2);
0801: MovieManageableCollection mlist2 = new MovieManageableCollectionImpl();
0802: MovieManageableCollection mlist3 = new MovieManageableCollectionImpl();
0803: a1.setMovies(mlist1);
0804: a2.setMovies(mlist2);
0805: a3.setMovies(mlist3);
0806:
0807: return m;
0808: }
0809:
0810: Actor buildActorWithMovies(String postfixId) {
0811: Actor a = new Actor("John Cusack" + postfixId);
0812: MovieManageableCollection list = new MovieManageableCollectionImpl();
0813: list.add(new MovieImpl("a_" + postfixId, "High Fidelity",
0814: "A comedy about fear of commitment, hating your job..."
0815: + postfixId));
0816: list.add(new MovieImpl("b_" + postfixId, "Identity",
0817: "When a nasty storm hits a hotel, ten strangers are stranded within ..."
0818: + postfixId));
0819: list
0820: .add(new MovieImpl(
0821: "c_" + postfixId,
0822: "Grosse Pointe Blank",
0823: "Martin Blank is a professional assassin. He is sent on a mission to a small Detroit ..."
0824: + postfixId));
0825: a.setMovies(list);
0826: return a;
0827: }
0828:
0829: void changeActorCollectionDescriptorTo(boolean autoRetrieve,
0830: int autoUpdate, int autoDelete, boolean proxy) {
0831: ojbChangeReferenceSetting(Actor.class, "movies", autoRetrieve,
0832: autoUpdate, autoDelete, proxy);
0833: }
0834:
0835: void changeMovieCollectionDescriptorTo(boolean autoRetrieve,
0836: int autoUpdate, int autoDelete, boolean proxy) {
0837: ojbChangeReferenceSetting(MovieImpl.class, "actors",
0838: autoRetrieve, autoUpdate, autoDelete, proxy);
0839: ojbChangeReferenceSetting(MovieImpl.class, "actors2",
0840: autoRetrieve, autoUpdate, autoDelete, proxy);
0841: }
0842:
0843: //=======================================================================
0844: // Inner classes, persistence capable test classes
0845: //=======================================================================
0846:
0847: public static interface MovieManageableCollection extends
0848: ManageableCollection {
0849: public Iterator iterator();
0850:
0851: public int size();
0852:
0853: public boolean isEmpty();
0854:
0855: public void clear();
0856:
0857: public boolean add(Movie movie);
0858:
0859: public boolean remove(Movie movie);
0860:
0861: public boolean contains(Movie movie);
0862:
0863: public Movie get(int index);
0864: }
0865:
0866: public static class MovieManageableCollectionImpl implements
0867: MovieManageableCollection {
0868: private ArrayList list = new ArrayList();
0869:
0870: public void ojbAdd(Object anObject) {
0871: list.add(anObject);
0872: }
0873:
0874: public void ojbAddAll(ManageableCollection otherCollection) {
0875: Iterator it = otherCollection.ojbIterator();
0876: while (it.hasNext()) {
0877: list.add(it.next());
0878: }
0879: }
0880:
0881: public Iterator ojbIterator() {
0882: return list.iterator();
0883: }
0884:
0885: public void afterStore(PersistenceBroker broker)
0886: throws PersistenceBrokerException {
0887: }
0888:
0889: public Iterator iterator() {
0890: return list.iterator();
0891: }
0892:
0893: public int size() {
0894: return list.size();
0895: }
0896:
0897: public boolean isEmpty() {
0898: return list.isEmpty();
0899: }
0900:
0901: public void clear() {
0902: list.clear();
0903: }
0904:
0905: public boolean add(Movie movie) {
0906: return list.add(movie);
0907: }
0908:
0909: public boolean remove(Movie movie) {
0910: return list.remove(movie);
0911: }
0912:
0913: public boolean contains(Movie movie) {
0914: return list.contains(movie);
0915: }
0916:
0917: public Movie get(int index) {
0918: return (Movie) list.get(index);
0919: }
0920: }
0921:
0922: public static class Actor {
0923: private Integer id;
0924: private Integer id2;
0925: private String name;
0926: private MovieManageableCollection movies;
0927:
0928: public Actor() {
0929: }
0930:
0931: public Actor(String name) {
0932: this .name = name;
0933: }
0934:
0935: public MovieManageableCollection getMovies() {
0936: return movies;
0937: }
0938:
0939: public void setMovies(MovieManageableCollection movies) {
0940: this .movies = movies;
0941: }
0942:
0943: public Integer getId() {
0944: return id;
0945: }
0946:
0947: public void setId(Integer id) {
0948: this .id = id;
0949: }
0950:
0951: public Integer getId2() {
0952: return id2;
0953: }
0954:
0955: public void setId2(Integer id2) {
0956: this .id2 = id2;
0957: }
0958:
0959: public String getName() {
0960: return name;
0961: }
0962:
0963: public void setName(String name) {
0964: this .name = name;
0965: }
0966:
0967: public String toString() {
0968: return ToStringBuilder.reflectionToString(this ).toString();
0969: }
0970: }
0971:
0972: public static interface Movie {
0973: public void addActors(Actor actor);
0974:
0975: public void addActors2(Actor actor);
0976:
0977: public Collection getActors();
0978:
0979: public void setActors(Collection actors);
0980:
0981: public List getActors2();
0982:
0983: public void setActors2(List actors);
0984:
0985: public Integer getIdInt2();
0986:
0987: public Integer getIdInt();
0988:
0989: public void setIdInt2(Integer id2Int);
0990:
0991: public void setIdInt(Integer idInt);
0992:
0993: public String getIdStr();
0994:
0995: public void setIdStr(String idStr);
0996:
0997: public String getTitle();
0998:
0999: public void setTitle(String title);
1000:
1001: public String getDescription();
1002:
1003: public void setDescription(String description);
1004: }
1005:
1006: public static class MovieImpl implements Movie {
1007: private Integer idInt;
1008: private Integer idInt2;
1009: private String idStr;
1010: private String title;
1011: private String description;
1012: private Collection actors;
1013: private List actors2;
1014:
1015: public MovieImpl() {
1016: }
1017:
1018: public MovieImpl(String idStr, String title, String description) {
1019: this .idStr = idStr;
1020: this .title = title;
1021: this .description = description;
1022: }
1023:
1024: public void addActors(Actor actor) {
1025: if (actors == null) {
1026: actors = new ArrayList();
1027: }
1028: if (!actors.contains(actor))
1029: actors.add(actor);
1030: else
1031: throw new OJBRuntimeException(
1032: "Can't add same object twice");
1033: }
1034:
1035: public void addActors2(Actor actor) {
1036: if (actors2 == null) {
1037: actors2 = new ArrayList();
1038: }
1039: if (!actors2.contains(actor))
1040: actors2.add(actor);
1041: else
1042: throw new OJBRuntimeException(
1043: "Can't add same object twice");
1044: }
1045:
1046: public Collection getActors() {
1047: return actors;
1048: }
1049:
1050: public void setActors(Collection actors) {
1051: this .actors = actors;
1052: }
1053:
1054: public List getActors2() {
1055: return actors2;
1056: }
1057:
1058: public void setActors2(List actors) {
1059: this .actors2 = actors;
1060: }
1061:
1062: public Integer getIdInt() {
1063: return idInt;
1064: }
1065:
1066: public void setIdInt(Integer idInt) {
1067: this .idInt = idInt;
1068: }
1069:
1070: public Integer getIdInt2() {
1071: return idInt2;
1072: }
1073:
1074: public void setIdInt2(Integer idInt2) {
1075: this .idInt2 = idInt2;
1076: }
1077:
1078: public String getIdStr() {
1079: return idStr;
1080: }
1081:
1082: public void setIdStr(String idStr) {
1083: this .idStr = idStr;
1084: }
1085:
1086: public String getTitle() {
1087: return title;
1088: }
1089:
1090: public void setTitle(String title) {
1091: this .title = title;
1092: }
1093:
1094: public String getDescription() {
1095: return description;
1096: }
1097:
1098: public void setDescription(String description) {
1099: this .description = description;
1100: }
1101:
1102: public String toString() {
1103: return ToStringBuilder.reflectionToString(this ).toString();
1104: }
1105: }
1106:
1107: public static class Role {
1108: private Integer actorId;
1109: private Integer actorId2;
1110: private Integer movieIntId;
1111: private Integer movieIntId2;
1112: private String movieStrId;
1113:
1114: public Role() {
1115: }
1116:
1117: public Integer getActorId() {
1118: return actorId;
1119: }
1120:
1121: public void setActorId(Integer actorId) {
1122: this .actorId = actorId;
1123: }
1124:
1125: public Integer getMovieIntId() {
1126: return movieIntId;
1127: }
1128:
1129: public Integer getMovieIntId2() {
1130: return movieIntId2;
1131: }
1132:
1133: public void setMovieIntId2(Integer movieIntId2) {
1134: this .movieIntId2 = movieIntId2;
1135: }
1136:
1137: public Integer getActorId2() {
1138: return actorId2;
1139: }
1140:
1141: public void setActorId2(Integer actorId2) {
1142: this .actorId2 = actorId2;
1143: }
1144:
1145: public void setMovieIntId(Integer movieIntId) {
1146: this .movieIntId = movieIntId;
1147: }
1148:
1149: public String getMovieStrId() {
1150: return movieStrId;
1151: }
1152:
1153: public void setMovieStrId(String movieStrId) {
1154: this .movieStrId = movieStrId;
1155: }
1156:
1157: public String toString() {
1158: return ToStringBuilder.reflectionToString(this ).toString();
1159: }
1160: }
1161:
1162: public static class County {
1163: private String id;
1164: private String name;
1165:
1166: public County() {
1167: }
1168:
1169: /**
1170: * Compares the given objects on the basis of their
1171: * toString() methods. Returns <code>false</code>
1172: * if the given object is not of type County.
1173: */
1174: public boolean equals(Object obj) {
1175: if (!(obj instanceof County)) {
1176: return false;
1177: }
1178: County other = (County) obj;
1179: return new EqualsBuilder().append(getId(), other.getId())
1180: .append(getName(), other.getName()).isEquals();
1181: }
1182:
1183: public String getId() {
1184: return id;
1185: }
1186:
1187: public void setId(String id) {
1188: this .id = id;
1189: }
1190:
1191: public String getName() {
1192: return name;
1193: }
1194:
1195: public void setName(String name) {
1196: this .name = name;
1197: }
1198: }
1199:
1200: public static interface OfficeProfile {
1201: public int getId();
1202:
1203: public void setId(int officeId);
1204:
1205: public void setName(String name);
1206:
1207: public String getName();
1208:
1209: public List getCounties();
1210:
1211: public void setCounties(List list);
1212:
1213: public void clearCounties();
1214:
1215: public void addCounty(County county);
1216:
1217: public void removeCounty(County county);
1218: }
1219:
1220: public static class OfficeProfileImpl implements OfficeProfile {
1221: private int id;
1222: private String name;
1223: private List counties;
1224:
1225: public OfficeProfileImpl() {
1226: }
1227:
1228: public boolean equals(Object obj) {
1229: if (!(obj instanceof OfficeProfile)) {
1230: return false;
1231: }
1232: OfficeProfile other = (OfficeProfile) obj;
1233: return new EqualsBuilder().append(getId(), other.getId())
1234: .append(getName(), other.getName()).append(
1235: getCounties(), other.getCounties())
1236: .isEquals();
1237: }
1238:
1239: public int getId() {
1240: return id;
1241: }
1242:
1243: public void setId(int officeId) {
1244: id = officeId;
1245: }
1246:
1247: public String getName() {
1248: return name;
1249: }
1250:
1251: public void setName(String name) {
1252: this .name = name;
1253: }
1254:
1255: public List getCounties() {
1256: return counties;
1257: }
1258:
1259: public void setCounties(List list) {
1260: counties = list;
1261: }
1262:
1263: public void clearCounties() {
1264: if (counties != null) {
1265: counties.clear();
1266: }
1267: }
1268:
1269: public void addCounty(County county) {
1270: if (counties == null) {
1271: counties = new LinkedList();
1272: }
1273: counties.add(county);
1274: }
1275:
1276: public void removeCounty(County county) {
1277: if (counties != null) {
1278: counties.remove(county);
1279: }
1280: }
1281: }
1282: }
|