001: package org.apache.ojb.broker;
002:
003: import org.apache.ojb.broker.metadata.ClassDescriptor;
004: import org.apache.ojb.broker.metadata.CollectionDescriptor;
005: import org.apache.ojb.broker.query.Criteria;
006: import org.apache.ojb.broker.query.Query;
007: import org.apache.ojb.broker.query.QueryByCriteria;
008: import org.apache.ojb.broker.query.QueryFactory;
009: import org.apache.ojb.junit.PBTestCase;
010:
011: import java.util.ArrayList;
012: import java.util.Collection;
013: import java.util.Iterator;
014: import java.util.List;
015: import java.util.Vector;
016:
017: /** This TestClass tests OJB facilities to work with polymorphism.
018: */
019: public class MtoNMapping extends PBTestCase {
020: public static void main(String[] args) {
021: String[] arr = { MtoNMapping.class.getName() };
022: junit.textui.TestRunner.main(arr);
023: }
024:
025: public MtoNMapping(String name) {
026: super (name);
027: }
028:
029: /**
030: * this tests if polymorph collections (i.e. collections of objects
031: * implementing a common interface) are treated correctly
032: */
033: public void testPolymorphMToN() {
034: Gourmet james = new Gourmet("james");
035: Identity jamesId = new Identity(james, broker);
036: Gourmet doris = new Gourmet("doris");
037: Identity dorisId = new Identity(doris, broker);
038:
039: Fish tuna = new Fish("tuna", 242, "salt");
040: Fish trout = new Fish("trout", 52, "fresh water");
041:
042: Salad radiccio = new Salad("Radiccio", 7, "red");
043: Salad lolloverde = new Salad("Lollo verde", 7, "green");
044:
045: james.addFavoriteFood(tuna);
046: james.addFavoriteFood(radiccio);
047:
048: doris.addFavoriteFood(tuna);
049: doris.addFavoriteFood(trout);
050: doris.addFavoriteFood(lolloverde);
051:
052: broker.beginTransaction();
053: broker.store(james);
054: broker.store(doris);
055: broker.commitTransaction();
056:
057: broker.clearCache();
058:
059: Gourmet loadedJames = (Gourmet) broker
060: .getObjectByIdentity(jamesId);
061: List favFood = loadedJames.getFavoriteFood();
062: assertEquals(2, favFood.size());
063:
064: Gourmet loadedDoris = (Gourmet) broker
065: .getObjectByIdentity(dorisId);
066: favFood = loadedDoris.getFavoriteFood();
067: assertEquals(3, favFood.size());
068: }
069:
070: public void testPolymorphMToNUpdate() {
071: long timestamp = System.currentTimeMillis();
072: Gourmet james = new Gourmet("james");
073: Identity jamesId = new Identity(james, broker);
074: Gourmet doris = new Gourmet("doris");
075: Identity dorisId = new Identity(doris, broker);
076:
077: Fish tuna = new Fish("tuna", 242, "salt");
078: Fish trout = new Fish("trout", 52, "fresh water");
079: Fish goldfish = new Fish("goldfish_" + timestamp, 10,
080: "brackish water");
081:
082: Salad radiccio = new Salad("Radiccio", 7, "red");
083: Salad lolloverde = new Salad("Lollo verde", 7, "green");
084:
085: james.addFavoriteFood(tuna);
086: james.addFavoriteFood(radiccio);
087:
088: doris.addFavoriteFood(tuna);
089: doris.addFavoriteFood(trout);
090: doris.addFavoriteFood(lolloverde);
091:
092: broker.beginTransaction();
093: broker.store(james);
094: broker.store(doris);
095: broker.commitTransaction();
096:
097: broker.clearCache();
098:
099: Gourmet loadedJames = (Gourmet) broker
100: .getObjectByIdentity(jamesId);
101: List favFood = loadedJames.getFavoriteFood();
102: assertEquals(2, favFood.size());
103:
104: Gourmet loadedDoris = (Gourmet) broker
105: .getObjectByIdentity(dorisId);
106: favFood = loadedDoris.getFavoriteFood();
107: assertEquals(3, favFood.size());
108:
109: /*
110: add new reference object
111: */
112: loadedDoris.addFavoriteFood(goldfish);
113: // update main object
114: broker.beginTransaction();
115: broker.store(loadedDoris);
116: broker.commitTransaction();
117:
118: broker.clearCache();
119: // query main object
120: loadedDoris = (Gourmet) broker.getObjectByIdentity(dorisId);
121: assertEquals(4, loadedDoris.getFavoriteFood().size());
122: }
123:
124: public void testPolymorphMToNDelete() {
125: long timestamp = System.currentTimeMillis();
126: Gourmet james = new Gourmet("james_" + timestamp);
127: Identity jamesId = new Identity(james, broker);
128: Gourmet doris = new Gourmet("doris_" + timestamp);
129: Identity dorisId = new Identity(doris, broker);
130:
131: Fish tuna = new Fish("tuna_" + timestamp, 242, "salt");
132: Fish trout = new Fish("trout_" + timestamp, 52, "fresh water");
133: Fish goldfish = new Fish("goldfish_" + timestamp, 10,
134: "brackish water");
135:
136: Salad radiccio = new Salad("Radiccio_" + timestamp, 7, "red");
137: Salad lolloverde = new Salad("Lollo verde_" + timestamp, 7,
138: "green");
139:
140: james.addFavoriteFood(tuna);
141: james.addFavoriteFood(radiccio);
142:
143: doris.addFavoriteFood(tuna);
144: doris.addFavoriteFood(trout);
145: doris.addFavoriteFood(lolloverde);
146: doris.addFavoriteFood(goldfish);
147:
148: broker.beginTransaction();
149: broker.store(james);
150: broker.store(doris);
151:
152: broker.commitTransaction();
153:
154: broker.clearCache();
155:
156: Gourmet loadedJames = (Gourmet) broker
157: .getObjectByIdentity(jamesId);
158: List favFood = loadedJames.getFavoriteFood();
159: assertEquals(2, favFood.size());
160:
161: Gourmet loadedDoris = (Gourmet) broker
162: .getObjectByIdentity(dorisId);
163: favFood = loadedDoris.getFavoriteFood();
164: assertEquals(4, favFood.size());
165:
166: Criteria c = new Criteria();
167: c.addLike("name", "%" + timestamp);
168: Query q = QueryFactory.newQuery(InterfaceFood.class, c);
169: Collection result = broker.getCollectionByQuery(q);
170: int foodBeforeRemove = result.size();
171: assertEquals("Wrong number of InterfaceFood objects", 5,
172: foodBeforeRemove);
173:
174: List foodList = loadedDoris.getFavoriteFood();
175: foodList.remove(0);
176: loadedDoris.setFavoriteFood(foodList);
177: // update main object
178: broker.beginTransaction();
179: broker.store(loadedDoris);
180: broker.commitTransaction();
181:
182: broker.clearCache();
183: // query main object
184: loadedDoris = (Gourmet) broker.getObjectByIdentity(dorisId);
185: assertEquals(3, loadedDoris.getFavoriteFood().size());
186: result = broker.getCollectionByQuery(q);
187: assertEquals("n-side object shouldn't be removed",
188: foodBeforeRemove, result.size());
189: }
190:
191: /** test loading of m:n mapped object nets*/
192: public void testMNLoading() throws Exception {
193: broker.clearCache();
194:
195: Person p = new Person();
196: p.setId(1);
197: Query q = QueryFactory.newQuery(p);
198: p = (Person) broker.getObjectByQuery(q);
199: assertNotNull(p);
200: Collection projects = p.getProjects();
201: assertNotNull(projects);
202: assertTrue(projects.size() > 0);
203:
204: projects.toArray(new Project[0]); // load it
205:
206: Criteria c = null;
207: q = QueryFactory.newQuery(Project.class, c);
208: Collection col = broker.getCollectionByQuery(q);
209: assertNotNull(col);
210: }
211:
212: /** test loading of m:n mapped object nets with prefetch*/
213: public void testMNLoadingPrefetch() throws Exception {
214: Criteria crit;
215: QueryByCriteria qry;
216: Collection col1, col2;
217:
218: broker.clearCache();
219:
220: crit = new Criteria();
221: crit.addLessThan("id", new Integer(6));
222: qry = QueryFactory.newQuery(Project.class, crit);
223: qry.addOrderByAscending("id");
224: col1 = broker.getCollectionByQuery(qry);
225: assertNotNull(col1);
226:
227: broker.clearCache();
228:
229: crit = new Criteria();
230: crit.addLessThan("id", new Integer(6));
231: qry = QueryFactory.newQuery(Project.class, crit);
232: qry.addOrderByAscending("id");
233: qry.addPrefetchedRelationship("persons");
234: col2 = broker.getCollectionByQuery(qry);
235: assertNotNull(col2);
236:
237: assertEquals("Same size", col1.size(), col2.size());
238:
239: Iterator it1 = col1.iterator();
240: Iterator it2 = col2.iterator();
241:
242: while (it1.hasNext() && it2.hasNext()) {
243: Project p1 = (Project) it1.next();
244: Project p2 = (Project) it2.next();
245:
246: assertEquals("Same Title", p1.getTitle(), p2.getTitle());
247: assertEquals("Same Number of Persons", p1.getPersons()
248: .size(), p2.getPersons().size());
249: assertEquals("Same toString", p1.toString(), p2.toString());
250: }
251: }
252:
253: /** test loading of m:n unidirectionally mapped objects*/
254: public void testMNLoadingUnidirectional() throws Exception {
255: broker.clearCache();
256:
257: PersonUnidirectional p = new PersonUnidirectional();
258: p.setId(1);
259: Query q = QueryFactory.newQuery(p);
260: p = (PersonUnidirectional) broker.getObjectByQuery(q);
261: Collection projects = p.getProjects();
262: assertNotNull(projects);
263: assertTrue(projects.size() > 0);
264: projects.toArray(new ProjectUnidirectional[0]); // load it
265: }
266:
267: /** test a manually build association via the association class Role*/
268: public void testLoadingWithAssociationClass() throws Exception {
269: Person p = new Person();
270: p.setId(1);
271: Query q = QueryFactory.newQuery(p);
272: p = (Person) broker.getObjectByQuery(q);
273:
274: Vector roles = (Vector) p.getRoles();
275: assertNotNull(roles);
276: //System.out.println(roles);
277:
278: Criteria c = null;
279: q = QueryFactory.newQuery(Project.class, c);
280: Collection col = broker.getCollectionByQuery(q);
281: assertNotNull(col);
282:
283: Iterator iter = col.iterator();
284: while (iter.hasNext()) {
285: iter.next();
286: //System.out.println(proj.getRoles());
287: }
288: }
289:
290: /** test inserting new objects to m:n association*/
291: public void testInsertion() throws Exception {
292: Person p = new Person();
293: p.setId(1);
294: Query q = QueryFactory.newQuery(p);
295: p = (Person) broker.getObjectByQuery(q);
296: assertNotNull(
297: "We should found a 'person' for id 1 - check db script",
298: p);
299: Collection projects = p.getProjects();
300: assertNotNull(projects);
301: projects.toArray(new Project[0]); // load it
302: assertNotNull(
303: "Person should have some projects - check db script",
304: projects);
305: int count = projects.size();
306:
307: Project proj = new Project();
308: proj.setPersons(new ArrayList());
309: proj.setTitle("MARS");
310: proj.setDescription("colonization of planet Mars");
311:
312: p.getProjects().add(proj);
313: proj.getPersons().add(p);
314: assertEquals(count + 1, p.getProjects().size());
315:
316: broker.beginTransaction();
317: broker.store(p);
318: broker.commitTransaction();
319:
320: broker.clearCache();
321:
322: p = (Person) broker.getObjectByQuery(q);
323: assertEquals(count + 1, p.getProjects().size());
324: }
325:
326: /** Add a new Project, delete an existing Project */
327: public void testInsertAndDelete() throws Exception {
328: Person pers = new Person();
329: pers.setId(7);
330: Query query = QueryFactory.newQuery(pers);
331: pers = (Person) broker.getObjectByQuery(query);
332: Collection projects = pers.getProjects();
333: Project[] projectArray = (Project[]) projects
334: .toArray(new Project[0]);
335: Project oldProj, newProj;
336: int count = projects.size();
337:
338: oldProj = projectArray[0];
339: projects.remove(oldProj);
340:
341: newProj = new Project();
342: newProj.setTitle("Test Project1 for Person 7");
343: newProj.setDescription("This is a Test Project1 for Person 7");
344: projects.add(newProj);
345:
346: newProj = new Project();
347: newProj.setTitle("Test Project2 for Person 7");
348: newProj.setDescription("This is a Test Project2 for Person 7");
349: projects.add(newProj);
350:
351: broker.beginTransaction();
352: broker.store(pers);
353: broker.commitTransaction();
354:
355: broker.clearCache();
356:
357: pers = (Person) broker.getObjectByQuery(query);
358: assertEquals(count + 1, pers.getProjects().size());
359:
360: }
361:
362: /**
363: * Create a project with two persons
364: * @param title
365: * @return
366: * @throws Exception
367: */
368: private Project createProjectWithAssignedPersons_1(String title)
369: throws Exception {
370: /*
371: the order of store statements is crucial because the relationship
372: pointing from Project to Person has auto-update=false
373: */
374: // create new project
375: Project project = new Project();
376: project.setTitle(title);
377:
378: // create two persons and assign project
379: // and assign persons with project
380: Person p1 = new Person();
381: p1.setFirstname(title);
382: broker.beginTransaction();
383:
384: broker.store(p1);
385:
386: List projects_1 = new ArrayList();
387: projects_1.add(project);
388: p1.setProjects(projects_1); // connect project to person
389:
390: Person p2 = new Person();
391: p2.setFirstname(title);
392: broker.store(p2);
393:
394: List projects_2 = new ArrayList();
395: projects_2.add(project);
396: p2.setProjects(projects_2); // connect project to person
397:
398: ArrayList persons = new ArrayList();
399: persons.add(p1);
400: persons.add(p2);
401: project.setPersons(persons); // connect persons to project
402:
403: broker.store(project);
404: broker.commitTransaction();
405:
406: return project;
407: }
408:
409: /**
410: * Create a project with two persons
411: * both relationships are set to auto-update=true
412: * @param title
413: * @return
414: * @throws Exception
415: */
416: private Project createProjectWithAssignedPersons_2(String title)
417: throws Exception {
418: ClassDescriptor cldProject = broker
419: .getClassDescriptor(Project.class);
420: CollectionDescriptor codPersons = cldProject
421: .getCollectionDescriptorByName("persons");
422: boolean cascadeStorePersons = codPersons.getCascadeStore();
423:
424: ClassDescriptor cldPerson = broker
425: .getClassDescriptor(Person.class);
426: CollectionDescriptor codProjects = cldPerson
427: .getCollectionDescriptorByName("projects");
428: boolean cascadeStoreProjects = codProjects.getCascadeStore();
429:
430: // temporarily set auto-update = true
431: codPersons.setCascadeStore(true);
432: codProjects.setCascadeStore(true);
433:
434: // create new project
435: Project project = new Project();
436: project.setTitle(title);
437:
438: // create two persons and assign project
439: // and assign persons with project
440: Person p1 = new Person();
441: p1.setFirstname(title);
442:
443: List projects_1 = new ArrayList();
444: projects_1.add(project);
445: p1.setProjects(projects_1); // connect project to person
446:
447: Person p2 = new Person();
448: p2.setFirstname(title);
449:
450: List projects_2 = new ArrayList();
451: projects_2.add(project);
452: p2.setProjects(projects_2); // connect project to person
453:
454: ArrayList persons = new ArrayList();
455: persons.add(p1);
456: persons.add(p2);
457: project.setPersons(persons); // connect persons to project
458:
459: broker.beginTransaction();
460: broker.store(project);
461: broker.commitTransaction();
462:
463: // reset original value
464: codPersons.setCascadeStore(cascadeStorePersons);
465: codProjects.setCascadeStore(cascadeStoreProjects);
466:
467: return project;
468: }
469:
470: /**
471: * Add two new persons and one new project. Assign persons with the
472: * new project and vice versa.
473: */
474: public void testInsertWithIndirectionTable_1() throws Exception {
475: String title = "testInsertWithIndirectionTable_1_"
476: + System.currentTimeMillis();
477:
478: Project project = createProjectWithAssignedPersons_1(title);
479:
480: verifyProjectWithAssignedPersons(title, project);
481: }
482:
483: /**
484: * Add two new persons and one new project. Assign persons with the
485: * new project and vice versa.
486: * both relationships are set to auto-update=true
487: */
488: public void testInsertWithIndirectionTable_2() throws Exception {
489: String title = "testInsertWithIndirectionTable_2_"
490: + System.currentTimeMillis();
491:
492: Project project = createProjectWithAssignedPersons_2(title);
493:
494: verifyProjectWithAssignedPersons(title, project);
495: }
496:
497: private void verifyProjectWithAssignedPersons(String title,
498: Project project) {
499: /*
500: Now I expect two entries in PERSON_PROJECT table
501: with same project id, two new Person and one Project
502: entries in PERSON/PROJECT table
503: */
504: broker.clearCache();
505: Criteria crit = new Criteria();
506: crit.addEqualTo("firstname", title);
507: Query query = new QueryByCriteria(Person.class, crit);
508: Collection result = broker.getCollectionByQuery(query);
509: assertNotNull(result);
510: assertEquals("We expect 2 person instances", 2, result.size());
511:
512: crit = new Criteria();
513: crit.addEqualTo("id", new Integer(project.getId()));
514: query = new QueryByCriteria(Project.class, crit);
515: result = broker.getCollectionByQuery(query);
516: assertNotNull(result);
517: assertEquals("We expect 1 project instance", 1, result.size());
518: Project newProject = (Project) result.iterator().next();
519: assertNotNull(newProject.getRoles());
520: assertEquals("We expect 2 Role objects", 2, newProject
521: .getRoles().size());
522:
523: // query for role objects representing PERSON_PROJECT entries
524: crit = new Criteria();
525: crit.addEqualTo("project_id", new Integer(project.getId()));
526: query = new QueryByCriteria(Role.class, crit);
527: result = broker.getCollectionByQuery(query);
528: assertNotNull(result);
529: assertEquals("We expect 2 role instances", 2, result.size());
530: }
531:
532: /**
533: * Add two new persons to existing project. Assign persons with the
534: * existing project and vice versa.
535: */
536: public void testInsertWithIndirectionTable_3() throws Exception {
537: String title = "testInsertWithIndirectionTable_3_"
538: + System.currentTimeMillis();
539:
540: // first we create an project with assigned persons
541: // create new project with two assigned persons
542: Project tempProject = createProjectWithAssignedPersons_1(title);
543:
544: // now the real update test begins
545: broker.clearCache();
546: Criteria critProject = new Criteria();
547: critProject.addEqualTo("id", new Integer(tempProject.getId()));
548: Query projectQuery = new QueryByCriteria(Project.class,
549: critProject);
550:
551: Criteria critPerson = new Criteria();
552: critPerson.addEqualTo("firstname", title);
553: Query personQuery = new QueryByCriteria(Person.class,
554: critPerson);
555:
556: broker.clearCache();
557:
558: // first we lookup roles for existing project
559: // query for role objects representing PERSON_PROJECT entries
560: Criteria crit = new Criteria();
561: crit.addEqualTo("project_id", new Integer(tempProject.getId()));
562: Query query = new QueryByCriteria(Role.class, crit);
563: Collection result = broker.getCollectionByQuery(query);
564: assertNotNull(result);
565: assertTrue("test needs existing roles for given id", result
566: .size() > 0);
567: int roleCount = result.size();
568:
569: // lookup the existing project
570: Project project = (Project) broker
571: .getObjectByQuery(projectQuery);
572: assertNotNull(project);
573:
574: // create two persons and assign project
575: Person p1 = new Person();
576: p1.setFirstname(title);
577: broker.beginTransaction();
578: broker.store(p1);
579:
580: List projects_1 = new ArrayList();
581: projects_1.add(project);
582: p1.setProjects(projects_1);
583:
584: Person p2 = new Person();
585: p2.setFirstname(title);
586: broker.store(p2);
587:
588: List projects_2 = new ArrayList();
589: projects_2.add(project);
590: p2.setProjects(projects_2);
591:
592: // connect persons to project
593: project.getPersons().add(p1);
594: project.getPersons().add(p2);
595:
596: broker.store(project);
597: broker.commitTransaction();
598:
599: result = broker.getCollectionByQuery(personQuery);
600: assertNotNull(result);
601: assertEquals("We expect 2 new person instances", 2 + 2, result
602: .size());
603:
604: /*
605: Now I expect two new entries in PERSON_PROJECT table
606: with same project id, two new Person entries
607: */
608: broker.clearCache();
609:
610: result = broker.getCollectionByQuery(personQuery);
611: assertNotNull(result);
612: assertEquals("We expect 2 new person instances", 2 + 2, result
613: .size());
614:
615: crit = new Criteria();
616: crit.addEqualTo("id", new Integer(project.getId()));
617: query = new QueryByCriteria(Project.class, crit);
618: result = broker.getCollectionByQuery(query);
619: assertNotNull(result);
620: assertEquals("We expect 1 project instance", 1, result.size());
621: Project newProject = (Project) result.iterator().next();
622: assertNotNull(newProject.getRoles());
623: assertEquals("We expect 2 new Role objects", roleCount + 2,
624: newProject.getRoles().size());
625:
626: // query for role objects representing PERSON_PROJECT entries
627: crit = new Criteria();
628: crit.addEqualTo("project_id", new Integer(project.getId()));
629: query = new QueryByCriteria(Role.class, crit);
630: result = broker.getCollectionByQuery(query);
631: assertNotNull(result);
632: assertEquals("We expect 2 role instances", roleCount + 2,
633: result.size());
634: }
635:
636: /** test deleting objects from an m:n association*/
637: public void testDeletion() throws Exception {
638: Person pers = new Person();
639: pers.setId(1);
640: Query query = QueryFactory.newQuery(pers);
641: pers = (Person) broker.getObjectByQuery(query);
642: Collection projects = pers.getProjects();
643: Project[] projectArray = (Project[]) projects
644: .toArray(new Project[0]); // load it
645: assertNotNull(projects);
646: int count = projects.size();
647:
648: Project proj = projectArray[0];
649:
650: Criteria crit = new Criteria();
651: crit.addEqualTo("person_id", new Integer(pers.getId()));
652: crit.addEqualTo("project_id", new Integer(proj.getId()));
653: Query roleQuery = QueryFactory.newQuery(Role.class, crit);
654:
655: Role role = (Role) broker.getObjectByQuery(roleQuery);
656: assertNotNull(role);
657: //System.out.println(role.toString());
658:
659: broker.beginTransaction();
660: broker.delete(proj);
661: broker.commitTransaction();
662:
663: broker.clearCache();
664:
665: pers = (Person) broker.getObjectByQuery(query);
666: assertEquals(count - 1, pers.getProjects().size());
667: role = (Role) broker.getObjectByQuery(roleQuery);
668: assertNull(role);
669: }
670:
671: /**
672: * delete all projects of a person
673: */
674: public void testDeleteUnidirectional() throws Exception {
675: PersonUnidirectional p = new PersonUnidirectional();
676: p.setId(1);
677: Query q = QueryFactory.newQuery(p);
678: p = (PersonUnidirectional) broker.getObjectByQuery(q);
679: Collection projects = p.getProjects();
680: Collection originalProjects;
681: projects.toArray(new ProjectUnidirectional[0]); // load it
682: originalProjects = new Vector();
683: originalProjects.addAll(projects);
684:
685: assertNotNull(projects);
686: int count = projects.size();
687:
688: ProjectUnidirectional proj = new ProjectUnidirectional();
689: proj.setTitle("GALVIN");
690: proj.setDescription("galvins project");
691:
692: p.getProjects().add(proj);
693: broker.beginTransaction();
694: broker.store(p);
695: broker.commitTransaction();
696:
697: broker.clearCache();
698:
699: p = (PersonUnidirectional) broker.getObjectByQuery(q);
700:
701: assertEquals(count + 1, p.getProjects().size());
702:
703: broker.beginTransaction();
704:
705: projects = p.getProjects();
706: projects.clear();
707: p.setProjects(projects);
708:
709: broker.store(p);
710: broker.commitTransaction();
711:
712: broker.clearCache();
713:
714: p = (PersonUnidirectional) broker.getObjectByQuery(q);
715: assertEquals(0, p.getProjects().size());
716:
717: // restore originals
718: broker.beginTransaction();
719: p.setProjects(originalProjects);
720: broker.store(p);
721: broker.delete(proj);
722: broker.commitTransaction();
723: }
724: }
|