001: /**
002: * (C) 2003 ppi Media
003: * User: om
004: */package org.apache.ojb.odmg;
005:
006: import java.util.ArrayList;
007: import java.util.Arrays;
008: import java.util.Collection;
009: import java.util.List;
010:
011: import org.apache.ojb.junit.ODMGTestCase;
012: import org.apache.ojb.odmg.shared.Person;
013: import org.apache.ojb.odmg.shared.PersonImpl;
014: import org.apache.commons.lang.ArrayUtils;
015: import org.apache.commons.collections.ListUtils;
016: import org.odmg.OQLQuery;
017: import org.odmg.Transaction;
018:
019: /**
020: * class PersonWithArrayTest
021: *
022: * @author <a href="mailto:om@ppi.de">Oliver Matz</a>
023: * @version $Id: $
024: */
025: public class PersonWithArrayTest extends ODMGTestCase {
026: public static void main(String[] args) {
027: String[] arr = { PersonWithArrayTest.class.getName() };
028: junit.textui.TestRunner.main(arr);
029: }
030:
031: /*
032: * lock only the father, let OJB do the rest
033: * delete father then children
034: */
035: public void testStoreDeleteThreePersons_1() throws Exception {
036: String postfix = "_" + System.currentTimeMillis();
037: String firstnameFather = "Father" + postfix;
038: String firstnameChild_1 = "Child_One" + postfix;
039: String firstnameChild_2 = "Child_Two" + postfix;
040: String lastname = "testStoreThreePersons_1_" + postfix;
041:
042: Person father = createPerson(firstnameFather, lastname, null,
043: null);
044: Person child_1 = createPerson(firstnameChild_1, lastname, null,
045: null);
046: Person child_2 = createPerson(firstnameChild_2, lastname, null,
047: null);
048:
049: Person[] children = new Person[] { child_1, child_2 };
050: father.setChildren(children);
051: child_1.setFather(father);
052: child_2.setFather(father);
053:
054: /*
055: * lock only the father, let OJB do the rest
056: */
057: TransactionExt tx = (TransactionExt) odmg.newTransaction();
058: tx.begin();
059: tx.lock(father, Transaction.WRITE);
060: tx.commit();
061:
062: tx.begin();
063: // make sure all objects are retrieved freshly in subsequent transactions
064: ((TransactionImpl) tx).getBroker().clearCache();
065: OQLQuery qry = odmg.newOQLQuery();
066: qry.create("select a from " + PersonImpl.class.getName()
067: + " where firstname=$1");
068: qry.bind(firstnameFather);
069: Collection result = (Collection) qry.execute();
070:
071: assertEquals("Exactly one element in result set", 1, result
072: .size());
073: Person returnedFather = (Person) result.iterator().next();
074: // should retrieve new instance
075: assertTrue("not same", returnedFather != father);
076: Person[] returnedChildren = returnedFather.getChildren();
077: assertNotNull(returnedChildren);
078: assertEquals(2, returnedChildren.length);
079: Person child = returnedChildren[0];
080: Person lookupFather = child.getFather();
081: assertNotNull(lookupFather);
082: assertEquals(returnedFather.getFirstname(), lookupFather
083: .getFirstname());
084: // unfortunately, PersonImpl does not have a suitable equals method.
085: assertEquals("children's names are equal", Arrays
086: .asList(getFirstNames(returnedChildren)), Arrays
087: .asList(getFirstNames(children)));
088: tx.commit();
089:
090: /*
091: delete father then children
092: fk-constraints?
093: */
094: tx.begin();
095: database.deletePersistent(returnedFather);
096: database.deletePersistent(returnedFather.getChildren()[0]);
097: database.deletePersistent(returnedFather.getChildren()[1]);
098:
099: tx.commit();
100:
101: qry = odmg.newOQLQuery();
102: qry.create("select a from " + PersonImpl.class.getName()
103: + " where firstname=$1");
104: qry.bind(firstnameFather);
105: result = (Collection) qry.execute();
106: assertEquals(0, result.size());
107:
108: qry = odmg.newOQLQuery();
109: qry.create("select a from " + PersonImpl.class.getName()
110: + " where firstname=$1");
111: qry.bind(firstnameChild_1);
112: result = (Collection) qry.execute();
113: // System.out.println("child: "+ new ArrayList(result));
114: assertEquals(0, result.size());
115: }
116:
117: /*
118: lock father then all childs
119: delete children then father
120: */
121: public void testStoreDeleteThreePersons_2() throws Exception {
122: String postfix = "_" + System.currentTimeMillis();
123: String firstnameFather = "Father" + postfix;
124: String firstnameChild_1 = "Child_One" + postfix;
125: String firstnameChild_2 = "Child_Two" + postfix;
126: String lastname = "testStoreThreePersons_2_" + postfix;
127:
128: Person father = createPerson(firstnameFather, lastname, null,
129: null);
130: Person child_1 = createPerson(firstnameChild_1, lastname, null,
131: null);
132: Person child_2 = createPerson(firstnameChild_2, lastname, null,
133: null);
134:
135: Person[] children = new Person[] { child_1, child_2 };
136: father.setChildren(children);
137: child_1.setFather(father);
138: child_2.setFather(father);
139:
140: /*
141: lock father then all childs
142: */
143: TransactionExt tx = (TransactionExt) odmg.newTransaction();
144: tx.begin();
145: tx.lock(father, Transaction.WRITE);
146: tx.lock(child_2, Transaction.WRITE);
147: tx.lock(child_1, Transaction.WRITE);
148:
149: tx.commit();
150: assertEquals(2, father.getChildren().length);
151:
152: tx.begin();
153: // make sure all objects are retrieved freshly in subsequent transactions
154: ((TransactionImpl) tx).getBroker().clearCache();
155: OQLQuery qry = odmg.newOQLQuery();
156: qry.create("select a from " + PersonImpl.class.getName()
157: + " where firstname=$1");
158: qry.bind(firstnameFather);
159: Collection result = (Collection) qry.execute();
160:
161: assertEquals("Exactly one element in result set", 1, result
162: .size());
163: Person returnedFather = (Person) result.iterator().next();
164: // should retrieve new instance
165: assertTrue("not same", returnedFather != father);
166: Person[] returnedChildren = returnedFather.getChildren();
167: assertNotNull(returnedChildren);
168: // check original instance again
169: assertEquals(2, father.getChildren().length);
170: assertEquals(2, returnedChildren.length);
171: Person child = returnedChildren[0];
172: Person lookupFather = child.getFather();
173: assertNotNull(lookupFather);
174: assertEquals(returnedFather.getFirstname(), lookupFather
175: .getFirstname());
176: // unfortunately, PersonImpl does not have a suitable equals method.
177: assertEquals("children's names are equal", Arrays
178: .asList(getFirstNames(returnedChildren)), Arrays
179: .asList(getFirstNames(children)));
180: // System.out.println(Arrays.asList(getFirstNames(returnedChildren)));
181: tx.commit();
182:
183: /*
184: delete father only and disable cascading delete
185: */
186: tx.begin();
187: /*
188: by default cascading delete is enabled for 1:n relations, but we want to
189: delete the father without deleting the dependent childs, so change runtime
190: behavior of cascading delete
191: */
192: tx.setCascadingDelete(PersonImpl.class, "children", false);
193: database.deletePersistent(returnedFather);
194: tx.commit();
195:
196: qry = odmg.newOQLQuery();
197: qry.create("select a from " + PersonImpl.class.getName()
198: + " where firstname=$1");
199: qry.bind(firstnameFather);
200: result = (Collection) qry.execute();
201: assertEquals("Exactly one element in result set", 0, result
202: .size());
203:
204: qry = odmg.newOQLQuery();
205: qry.create("select a from " + PersonImpl.class.getName()
206: + " where lastname=$1");
207: qry.bind(lastname);
208: result = (Collection) qry.execute();
209: assertEquals(
210: "Expected the two children objects of deleted main object",
211: 2, result.size());
212: }
213:
214: /**
215: * Seems the locking order of objects is mandatory in this
216: * case. This test fails
217: */
218: public void testStoreDeleteThreePersons_3() throws Exception {
219: String postfix = "_" + System.currentTimeMillis();
220: String firstnameFather = "Father" + postfix;
221: String firstnameChild_1 = "Child_One" + postfix;
222: String firstnameChild_2 = "Child_Two" + postfix;
223: String lastname = "testStoreThreePersons_3" + postfix;
224:
225: Person father = createPerson(firstnameFather, lastname, null,
226: null);
227: Person child_1 = createPerson(firstnameChild_1, lastname, null,
228: null);
229: Person child_2 = createPerson(firstnameChild_2, lastname, null,
230: null);
231:
232: Person[] children = new Person[] { child_1, child_2 };
233: father.setChildren(children);
234: child_1.setFather(father);
235: child_2.setFather(father);
236:
237: /*
238: lock childs first, then lock father
239: TODO: Does not pass - why? A defined lock
240: order necessary?
241: if this doesn't make sense remove the test
242: */
243: Transaction tx = odmg.newTransaction();
244: tx.begin();
245: tx.lock(child_1, Transaction.WRITE);
246: tx.lock(child_2, Transaction.WRITE);
247: tx.lock(father, Transaction.WRITE);
248: tx.commit();
249:
250: tx = odmg.newTransaction();
251: tx.begin();
252: // make sure all objects are retrieved freshly in subsequent transactions
253: ((TransactionImpl) tx).getBroker().clearCache();
254:
255: OQLQuery qry = odmg.newOQLQuery();
256: qry.create("select a from " + PersonImpl.class.getName()
257: + " where lastname=$1");
258: qry.bind(lastname);
259: Collection result = (Collection) qry.execute();
260: assertEquals(3, new ArrayList(result).size());
261:
262: qry = odmg.newOQLQuery();
263: qry.create("select a from " + PersonImpl.class.getName()
264: + " where firstname=$1");
265: qry.bind(firstnameFather);
266: result = (Collection) qry.execute();
267: tx.commit();
268: assertEquals("Exactly one element in result set", 1, result
269: .size());
270:
271: tx.begin();
272: Person returnedFather = (Person) result.iterator().next();
273: // should retrieve new instance, cause we clear the cache
274: assertTrue("not same instance expected",
275: returnedFather != father);
276: Person[] returnedChildren = returnedFather.getChildren();
277: assertNotNull(returnedChildren);
278: assertEquals(2, returnedChildren.length);
279: Person child = returnedChildren[0];
280: Person lookupFather = child.getFather();
281: assertNotNull(lookupFather);
282: assertEquals(returnedFather.getFirstname(), lookupFather
283: .getFirstname());
284: // unfortunately, PersonImpl does not have a suitable equals method.
285: // comment out, because of child object order problem (it's not a bug, it's bad test writing)
286: // assertEquals(
287: // "children's names are equal",
288: // Arrays.asList(getFirstNames(returnedChildren)),
289: // Arrays.asList(getFirstNames(children)));
290: // we expect the same names in both array, thus intersection result have to be '2'
291: List list = ListUtils.intersection(Arrays
292: .asList(getFirstNames(returnedChildren)), Arrays
293: .asList(getFirstNames(children)));
294: assertEquals(2, list.size());
295: // System.out.println(Arrays.asList(getFirstNames(returnedChildren)));
296: tx.commit();
297:
298: /*
299: delete father then children
300: fk-constraints?
301: Delete calls in wrong order
302: */
303: tx.begin();
304: database.deletePersistent(returnedFather);
305: database.deletePersistent(returnedFather.getChildren()[0]);
306: database.deletePersistent(returnedFather.getChildren()[1]);
307: tx.commit();
308:
309: qry = odmg.newOQLQuery();
310: qry.create("select a from " + PersonImpl.class.getName()
311: + " where firstname=$1");
312: qry.bind(firstnameFather);
313: result = (Collection) qry.execute();
314: assertEquals("Exactly one element in result set", 0, result
315: .size());
316:
317: qry = odmg.newOQLQuery();
318: qry.create("select a from " + PersonImpl.class.getName()
319: + " where firstname=$1");
320: qry.bind(firstnameChild_1);
321: result = (Collection) qry.execute();
322: // System.out.println("child: "+result.iterator().next());
323: assertEquals("Exactly one element in result set", 0, result
324: .size());
325: }
326:
327: private Person createPerson(String firstname, String lastname,
328: Person father, Person mother) {
329: Person p = new PersonImpl();
330: p.setFirstname(firstname);
331: p.setLastname(lastname);
332: p.setFather(father);
333: p.setMother(mother);
334: // p.setChildren(null);
335: return p;
336: }
337:
338: private static String[] getFirstNames(Person[] persons) {
339: int length = persons == null ? 0 : persons.length;
340: String[] ret = new String[length];
341: for (int i = 0; i < ret.length; i++) {
342: ret[i] = persons[i].getFirstname();
343: }
344: return ret;
345: }
346: }
|