001: package org.apache.ojb.broker;
002:
003: import java.util.ArrayList;
004: import java.util.Arrays;
005: import java.util.Collection;
006: import java.util.Iterator;
007: import java.util.List;
008:
009: import org.apache.ojb.broker.metadata.ClassDescriptor;
010: import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
011: import org.apache.ojb.broker.query.Criteria;
012: import org.apache.ojb.broker.query.QueryByCriteria;
013: import org.apache.ojb.junit.JUnitExtensions;
014:
015: /**
016: * Tests multithreaded read of objects using proxy for nested 1:1 references
017: * Account --> Buyer --> Address --> AddressType
018: *
019: * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
020: * @version $Id: MultithreadedReadTest.java,v 1.3.2.2 2004/09/30 13:52:02 arminw Exp $
021: */
022: public class MultithreadedReadTest extends
023: JUnitExtensions.MultiThreadedTestCase {
024: static final int NONE = ObjectReferenceDescriptor.CASCADE_NONE;
025: static final int LINK = ObjectReferenceDescriptor.CASCADE_LINK;
026: static final int OBJECT = ObjectReferenceDescriptor.CASCADE_OBJECT;
027:
028: int loops = 2;
029: int concurrentThreads = 19;
030: int numberOfObjects = 30;
031:
032: public MultithreadedReadTest(String s) {
033: super (s);
034: }
035:
036: public static void main(String[] args) {
037: String[] arr = { MultithreadedReadTest.class.getName() };
038: junit.textui.TestRunner.main(arr);
039: }
040:
041: protected void setUp() throws Exception {
042: super .setUp();
043: }
044:
045: protected void tearDown() throws Exception {
046: PersistenceBroker broker = PersistenceBrokerFactory
047: .defaultPersistenceBroker();
048: try {
049: changeReferenceSetting(broker, AccountImpl.class, "buyer",
050: true, NONE, NONE, false);
051: changeReferenceSetting(broker, BuyerImpl.class, "address",
052: true, NONE, NONE, false);
053: changeReferenceSetting(broker, BuyerImpl.class, "invoices",
054: true, NONE, NONE, false);
055: changeReferenceSetting(broker, BuyerImpl.class, "articles",
056: true, NONE, NONE, false);
057: } finally {
058: if (broker != null) {
059: broker.close();
060: }
061: }
062: super .tearDown();
063: }
064:
065: public void testClosedPB() throws Throwable {
066: String name = "testClosedPB_" + System.currentTimeMillis();
067: Account account = null;
068: PersistenceBroker broker = null;
069: try {
070: broker = PersistenceBrokerFactory
071: .defaultPersistenceBroker();
072: changeReferenceSetting(broker, AccountImpl.class, "buyer",
073: true, OBJECT, OBJECT, false);
074: changeReferenceSetting(broker, BuyerImpl.class, "address",
075: true, OBJECT, OBJECT, false);
076: changeReferenceSetting(broker, BuyerImpl.class, "invoices",
077: true, OBJECT, OBJECT, false);
078: changeReferenceSetting(broker, BuyerImpl.class, "articles",
079: true, OBJECT, OBJECT, false);
080: broker.beginTransaction();
081: Integer[] ids = prepareTestRead(broker, name, 5);
082: broker.commitTransaction();
083: broker.clearCache();
084:
085: Criteria crit = new Criteria();
086: crit.addIn("id", Arrays.asList(ids));
087: QueryByCriteria query = new QueryByCriteria(Account.class,
088: crit);
089: Collection result = broker.getCollectionByQuery(query);
090: Iterator iter = result.iterator();
091: // iter.next();
092: account = (Account) iter.next();
093: while (iter.hasNext()) {
094: iter.next();
095: }
096: } finally {
097: if (broker != null)
098: broker.close();
099: }
100:
101: TestCaseRunnable tct[] = new TestCaseRunnable[50];
102: for (int i = 0; i < concurrentThreads; i++) {
103: tct[i] = new TestHandleMaterialize(account, name);
104: }
105: // run test classes
106: runTestCaseRunnables(tct);
107: }
108:
109: /**
110: * Read objects using lazy materialization for references from DB. Different threads
111: * call the references on the read objects
112: */
113: public void testObjectMaterializationByDifferentThread()
114: throws Exception {
115: for (int k = 0; k < loops; k++) {
116: String searchCriteria = "testObjectMaterializationByDifferentThread_"
117: + System.currentTimeMillis();
118: PersistenceBroker broker = null;
119: Collection accounts;
120: try {
121: broker = PersistenceBrokerFactory
122: .defaultPersistenceBroker();
123: changeReferenceSetting(broker, AccountImpl.class,
124: "buyer", true, OBJECT, OBJECT, false);
125: changeReferenceSetting(broker, BuyerImpl.class,
126: "address", true, OBJECT, OBJECT, true);
127: changeReferenceSetting(broker, BuyerImpl.class,
128: "invoices", true, OBJECT, OBJECT, true);
129: changeReferenceSetting(broker, BuyerImpl.class,
130: "articles", true, OBJECT, OBJECT, false);
131: broker.beginTransaction();
132: prepareTestRead(broker, searchCriteria,
133: concurrentThreads);
134: broker.commitTransaction();
135: broker.clearCache();
136:
137: Criteria crit = new Criteria();
138: crit.addEqualTo("name", searchCriteria);
139: QueryByCriteria query = new QueryByCriteria(
140: Account.class, crit);
141: accounts = broker.getCollectionByQuery(query);
142: assertEquals(concurrentThreads, accounts.size());
143: } finally {
144: if (broker != null)
145: broker.close();
146: }
147: Iterator iter = accounts.iterator();
148: TestCaseRunnable tct[] = new TestCaseRunnable[concurrentThreads];
149: for (int i = 0; i < concurrentThreads; i++) {
150: tct[i] = new TestHandleMaterialize((Account) iter
151: .next(), searchCriteria);
152: }
153: // run test classes
154: runTestCaseRunnables(tct);
155: }
156: }
157:
158: /**
159: * Different threads try to materialize the same bunch of objects.
160: */
161: public void testMultithreadedRead() throws Exception {
162: String searchCriteria = "testMultithreadedRead_"
163: + System.currentTimeMillis();
164: PersistenceBroker broker = null;
165: try {
166: broker = PersistenceBrokerFactory
167: .defaultPersistenceBroker();
168: changeReferenceSetting(broker, AccountImpl.class, "buyer",
169: true, OBJECT, OBJECT, false);
170: changeReferenceSetting(broker, BuyerImpl.class, "address",
171: true, OBJECT, OBJECT, false);
172: changeReferenceSetting(broker, BuyerImpl.class, "invoices",
173: true, OBJECT, OBJECT, false);
174: changeReferenceSetting(broker, BuyerImpl.class, "articles",
175: true, OBJECT, OBJECT, false);
176: broker.beginTransaction();
177: prepareTestRead(broker, searchCriteria, numberOfObjects);
178: broker.commitTransaction();
179: broker.clearCache();
180: } finally {
181: if (broker != null)
182: broker.close();
183: }
184:
185: System.out.println();
186: System.out.println("Multithreaded read of objects - start");
187: System.out.println("" + concurrentThreads
188: + " concurrent threads read " + numberOfObjects
189: + " objects per thread, loop " + loops + " times");
190: for (int k = 0; k < loops; k++) {
191: broker = PersistenceBrokerFactory
192: .defaultPersistenceBroker();
193: broker.clearCache();
194: broker.close();
195:
196: TestCaseRunnable tct[] = new TestCaseRunnable[concurrentThreads];
197: for (int i = 0; i < concurrentThreads; i++) {
198: tct[i] = new TestHandleRead(searchCriteria);
199: }
200: // run test classes
201: runTestCaseRunnables(tct);
202: }
203:
204: System.out.println("Multithreaded read of objects - end");
205: }
206:
207: /**
208: * Different threads try to materialize the same bunch of objects
209: */
210: public void testMultithreadedLazyRead() throws Exception {
211: String name = "testMultithreadedLazyRead"
212: + System.currentTimeMillis();
213: PersistenceBroker broker = null;
214: List identityList = null;
215: try {
216: broker = PersistenceBrokerFactory
217: .defaultPersistenceBroker();
218: changeReferenceSetting(broker, AccountImpl.class, "buyer",
219: true, OBJECT, OBJECT, false);
220: changeReferenceSetting(broker, BuyerImpl.class, "address",
221: true, OBJECT, OBJECT, true);
222: changeReferenceSetting(broker, BuyerImpl.class, "invoices",
223: true, OBJECT, OBJECT, true);
224: changeReferenceSetting(broker, BuyerImpl.class, "articles",
225: true, OBJECT, OBJECT, true);
226: broker.beginTransaction();
227: identityList = prepareTestLazyRead(broker, name,
228: concurrentThreads);
229: broker.commitTransaction();
230: broker.clearCache();
231: } finally {
232: if (broker != null)
233: broker.close();
234: }
235:
236: System.out.println();
237: System.out
238: .println("Multithreaded lazy read of objects - start");
239: System.out.println("" + concurrentThreads
240: + " concurrent threads read different object with lazy"
241: + " materialization reference, loop " + loops
242: + " times");
243: for (int k = 0; k < loops; k++) {
244: broker = PersistenceBrokerFactory
245: .defaultPersistenceBroker();
246: broker.clearCache();
247: broker.close();
248:
249: TestCaseRunnable tct[] = new TestCaseRunnable[concurrentThreads];
250: for (int i = 0; i < concurrentThreads; i++) {
251: tct[i] = new TestHandleLazyRead(identityList, name);
252: }
253: // run test classes
254: runTestCaseRunnables(tct);
255: }
256: System.out.println("Multithreaded lazy read of objects - end");
257: }
258:
259: private Integer[] prepareTestRead(PersistenceBroker broker,
260: String name, int numbers) throws Exception {
261: Integer[] ids = new Integer[numbers];
262: for (int i = 0; i < numbers; i++) {
263: AddressType type = new AddressTypeImpl(name);
264: Address address = new AddressImpl(name, type);
265: Buyer buyer = new BuyerImpl(name, address);
266: buyer.setArticles(buildArticles(name, numbers));
267: buyer.setInvoices(buildInvoices(name, numbers));
268: Account account = new AccountImpl(name, buyer);
269: broker.store(account);
270: ids[i] = account.getId();
271: }
272: return ids;
273: }
274:
275: private List prepareTestLazyRead(PersistenceBroker broker,
276: String searchCriteria, int numbers) throws Exception {
277: List result = new ArrayList();
278: for (int i = 0; i < numbers; i++) {
279: AddressType type = new AddressTypeImpl(searchCriteria);
280: Address address = new AddressImpl(searchCriteria, type);
281: Buyer buyer = new BuyerImpl(searchCriteria, address);
282: buyer.setArticles(buildArticles(searchCriteria, numbers));
283: buyer.setInvoices(buildInvoices(searchCriteria, numbers));
284: Account account = new AccountImpl(searchCriteria, buyer);
285: broker.store(account);
286: Identity oid = broker.serviceIdentity().buildIdentity(
287: account);
288: result.add(oid);
289: }
290: return result;
291: }
292:
293: private List buildInvoices(String name, int numbers) {
294: List result = new ArrayList();
295: for (int i = 0; i < numbers; i++) {
296: String invoiceNumber = "I_"
297: + (long) (Math.random() * Long.MAX_VALUE);
298: Invoice invoice = new InvoiceImpl(name, invoiceNumber);
299: result.add(invoice);
300: }
301: return result;
302: }
303:
304: private List buildArticles(String name, int numbers) {
305: List result = new ArrayList();
306: for (int i = 0; i < numbers; i++) {
307: Article a = new ArticleImpl(name, "a article description");
308: result.add(a);
309: }
310: return result;
311: }
312:
313: void changeReferenceSetting(PersistenceBroker broker, Class clazz,
314: String fieldName, boolean autoRetrieve, int autoUpdate,
315: int autoDelete, boolean proxy) {
316: ClassDescriptor cld = broker.getClassDescriptor(clazz);
317: ObjectReferenceDescriptor descriptor = cld
318: .getCollectionDescriptorByName(fieldName);
319: if (descriptor == null) {
320: descriptor = cld
321: .getObjectReferenceDescriptorByName(fieldName);
322: }
323: if (descriptor == null) {
324: throw new RuntimeException("Field name " + fieldName
325: + " does not represent a reference in class '"
326: + clazz.getName() + "'");
327: }
328: descriptor.setLazy(proxy);
329: descriptor.setCascadeRetrieve(autoRetrieve);
330: descriptor.setCascadingStore(autoUpdate);
331: descriptor.setCascadingDelete(autoDelete);
332: }
333:
334: //***********************************************
335: // test handle of multithreaded test
336: //***********************************************
337: class TestHandleRead extends
338: JUnitExtensions.MultiThreadedTestCase.TestCaseRunnable {
339: String searchCriteria;
340:
341: public TestHandleRead(String searchCriteria) {
342: this .searchCriteria = searchCriteria;
343: }
344:
345: public void runTestCase() throws Throwable {
346: readByCollection();
347: readByIterator();
348: }
349:
350: private void readByCollection() throws Exception {
351: PersistenceBroker broker = null;
352: try {
353: broker = PersistenceBrokerFactory
354: .defaultPersistenceBroker();
355: broker.clearCache();
356: Criteria crit = new Criteria();
357: crit.addEqualTo("name", searchCriteria);
358: QueryByCriteria query = new QueryByCriteria(
359: Account.class, crit);
360: Collection accounts = broker
361: .getCollectionByQuery(query);
362: assertEquals("Wrong number of expected objects",
363: numberOfObjects, accounts.size());
364: for (Iterator iter = accounts.iterator(); iter
365: .hasNext();) {
366: Account account = (Account) iter.next();
367: assertEquals(searchCriteria, account.getName());
368: assertNotNull(
369: "All accounts have a reference to an Buyer",
370: account.getBuyer());
371: assertNotNull(
372: "All buyers have a reference to an Address",
373: account.getBuyer().getAddress());
374: assertNotNull(
375: "All addresses have a reference to an AdressType",
376: account.getBuyer().getAddress().getType());
377: assertNotNull("All AddressType have a name",
378: account.getBuyer().getAddress().getType()
379: .getName());
380: assertNotNull(
381: "All buyers have populated 1:n reference to Invoice",
382: account.getBuyer().getInvoices());
383: assertNotNull(
384: "All buyers have populated 1:n reference to Article",
385: account.getBuyer().getArticles());
386: // System.out.println(""+Thread.currentThread().toString()+": passed");
387: }
388: } finally {
389: if (broker != null)
390: broker.close();
391: }
392: }
393:
394: private void readByIterator() throws Exception {
395: PersistenceBroker broker = null;
396: try {
397: broker = PersistenceBrokerFactory
398: .defaultPersistenceBroker();
399: broker.clearCache();
400: Criteria crit = new Criteria();
401: crit.addEqualTo("name", searchCriteria);
402: QueryByCriteria query = new QueryByCriteria(
403: Account.class, crit);
404: Iterator iter = broker.getIteratorByQuery(query);
405: for (; iter.hasNext();) {
406: Account account = (Account) iter.next();
407: assertEquals(searchCriteria, account.getName());
408: assertNotNull(
409: "All accounts have a reference to an Buyer",
410: account.getBuyer());
411: assertNotNull(
412: "All buyers have a reference to an Address",
413: account.getBuyer().getAddress());
414: assertNotNull(
415: "All addresses have a reference to an AdressType",
416: account.getBuyer().getAddress().getType());
417: assertNotNull("All AddressType have a name",
418: account.getBuyer().getAddress().getType()
419: .getName());
420: assertNotNull(
421: "All buyers have populated 1:n reference to Invoice",
422: account.getBuyer().getInvoices());
423: assertNotNull(
424: "All buyers have populated 1:n reference to Article",
425: account.getBuyer().getArticles());
426: // System.out.println(""+Thread.currentThread().toString()+": passed");
427: }
428: } finally {
429: if (broker != null)
430: broker.close();
431: }
432: }
433: }
434:
435: class TestHandleLazyRead extends
436: JUnitExtensions.MultiThreadedTestCase.TestCaseRunnable {
437: List identityList;
438: String name;
439:
440: public TestHandleLazyRead(List identityList, String name) {
441: this .identityList = identityList;
442: this .name = name;
443: }
444:
445: public void runTestCase() throws Throwable {
446: PersistenceBroker broker = null;
447: Account account = null;
448: try {
449: broker = PersistenceBrokerFactory
450: .defaultPersistenceBroker();
451: Iterator it = identityList.iterator();
452: while (it.hasNext()) {
453: Identity oid = (Identity) it.next();
454: account = (Account) broker.getObjectByIdentity(oid);
455: }
456: } finally {
457: if (broker != null)
458: broker.close();
459: }
460: assertEquals(name, account.getName());
461: assertNotNull("All accounts have a reference to an Buyer",
462: account.getBuyer());
463: assertNotNull("All buyers have a reference to an Address",
464: account.getBuyer().getAddress());
465: assertNotNull(
466: "All addresses have a reference to an AdressType",
467: account.getBuyer().getAddress().getType());
468: assertNotNull("All AddressType have a name", account
469: .getBuyer().getAddress().getType().getName());
470: assertNotNull(
471: "All buyers have populated 1:n reference to Invoice",
472: account.getBuyer().getInvoices());
473: assertNotNull(
474: "All buyers have populated 1:n reference to Article",
475: account.getBuyer().getArticles());
476: }
477: }
478:
479: class TestHandleMaterialize extends
480: JUnitExtensions.MultiThreadedTestCase.TestCaseRunnable {
481: Account account;
482: String name;
483:
484: public TestHandleMaterialize(Account account, String name) {
485: this .account = account;
486: this .name = name;
487: }
488:
489: public void runTestCase() throws Throwable {
490: assertEquals(name, account.getName());
491: assertNotNull("All accounts have a reference to an Buyer",
492: account.getBuyer());
493: assertEquals(name, account.getBuyer().getName());
494: assertNotNull("All buyers have a reference to an Address",
495: account.getBuyer().getAddress());
496: assertEquals(name, account.getBuyer().getAddress()
497: .getName());
498: assertNotNull(
499: "All addresses have a reference to an AdressType",
500: account.getBuyer().getAddress().getType());
501: assertNotNull("All AddressType have a name", account
502: .getBuyer().getAddress().getType().getName());
503: assertNotNull(
504: "All buyers have populated 1:n reference to Invoice",
505: account.getBuyer().getInvoices());
506: assertNotNull(
507: "All buyers have populated 1:n reference to Article",
508: account.getBuyer().getArticles());
509: }
510: }
511:
512: //***********************************************
513: // test classes/interfaces starts here
514: //***********************************************
515: public interface Account extends Base {
516: Buyer getBuyer();
517:
518: void setBuyer(Buyer buyer);
519: }
520:
521: public static class AccountImpl extends BaseImpl implements Account {
522: Buyer buyer;
523:
524: public AccountImpl(String name, Buyer buyer) {
525: super (name);
526: this .buyer = buyer;
527: }
528:
529: public AccountImpl(Buyer buyer) {
530: this .buyer = buyer;
531: }
532:
533: public AccountImpl() {
534:
535: }
536:
537: public Buyer getBuyer() {
538: return buyer;
539: }
540:
541: public void setBuyer(Buyer buyer) {
542: this .buyer = buyer;
543: }
544: }
545:
546: public interface Buyer extends Base {
547: Address getAddress();
548:
549: void setAddress(Address address);
550:
551: public List getInvoices();
552:
553: public void setInvoices(List invoices);
554:
555: public List getArticles();
556:
557: public void setArticles(List articles);
558: }
559:
560: public static class BuyerImpl extends BaseImpl implements Buyer {
561: private Address address;
562: private List invoices;
563: private List articles;
564:
565: public BuyerImpl(String name, Address address) {
566: super (name);
567: this .address = address;
568: }
569:
570: public BuyerImpl(String name, Address address, List invoices,
571: List articles) {
572: super (name);
573: this .address = address;
574: this .invoices = invoices;
575: this .articles = articles;
576: }
577:
578: public BuyerImpl(Address address) {
579: this .address = address;
580: }
581:
582: public BuyerImpl() {
583:
584: }
585:
586: public List getInvoices() {
587: return invoices;
588: }
589:
590: public void setInvoices(List invoices) {
591: this .invoices = invoices;
592: }
593:
594: public List getArticles() {
595: return articles;
596: }
597:
598: public void setArticles(List articles) {
599: this .articles = articles;
600: }
601:
602: public Address getAddress() {
603: return address;
604: }
605:
606: public void setAddress(Address address) {
607: this .address = address;
608: }
609: }
610:
611: public interface Address extends Base {
612: AddressType getType();
613:
614: void setType(AddressType type);
615: }
616:
617: public static class AddressImpl extends BaseImpl implements Address {
618: AddressType type;
619:
620: public AddressImpl(String name, AddressType type) {
621: super (name);
622: this .type = type;
623: }
624:
625: public AddressImpl(AddressType type) {
626: this .type = type;
627: }
628:
629: public AddressImpl() {
630:
631: }
632:
633: public AddressType getType() {
634: return type;
635: }
636:
637: public void setType(AddressType type) {
638: this .type = type;
639: }
640: }
641:
642: public interface AddressType extends Base {
643: }
644:
645: public static class AddressTypeImpl extends BaseImpl implements
646: AddressType {
647: public AddressTypeImpl(String name) {
648: super (name);
649: }
650:
651: public AddressTypeImpl() {
652: }
653: }
654:
655: public interface Base {
656: Integer getId();
657:
658: void setId(Integer id);
659:
660: String getName();
661:
662: void setName(String name);
663: }
664:
665: public static class BaseImpl {
666: Integer id;
667: String name;
668:
669: public BaseImpl(String name) {
670: this .name = name;
671: }
672:
673: public BaseImpl() {
674: }
675:
676: public Integer getId() {
677: return id;
678: }
679:
680: public void setId(Integer id) {
681: this .id = id;
682: }
683:
684: public String getName() {
685: return name;
686: }
687:
688: public void setName(String name) {
689: this .name = name;
690: }
691: }
692:
693: public static interface Invoice extends Base {
694: public String getInvoiceNumber();
695:
696: public void setInvoiceNumber(String invoiceNumber);
697: }
698:
699: public static class InvoiceImpl extends BaseImpl implements Invoice {
700: private String invoiceNumber;
701: private Integer buyerId;
702:
703: public InvoiceImpl() {
704: }
705:
706: public InvoiceImpl(String name, String invoiceNumber) {
707: super (name);
708: this .invoiceNumber = invoiceNumber;
709: }
710:
711: public Integer getBuyerId() {
712: return buyerId;
713: }
714:
715: public void setBuyerId(Integer buyerId) {
716: this .buyerId = buyerId;
717: }
718:
719: public String getInvoiceNumber() {
720: return invoiceNumber;
721: }
722:
723: public void setInvoiceNumber(String invoiceNumber) {
724: this .invoiceNumber = invoiceNumber;
725: }
726: }
727:
728: public static interface Article extends Base {
729: public String getDescription();
730:
731: public void setDescription(String description);
732: }
733:
734: public static class ArticleImpl extends BaseImpl implements Article {
735: private String description;
736: private Integer buyerId;
737:
738: public ArticleImpl() {
739: }
740:
741: public ArticleImpl(String name, String description) {
742: super (name);
743: this .description = description;
744: }
745:
746: public Integer getBuyerId() {
747: return buyerId;
748: }
749:
750: public void setBuyerId(Integer buyerId) {
751: this .buyerId = buyerId;
752: }
753:
754: public String getDescription() {
755: return description;
756: }
757:
758: public void setDescription(String description) {
759: this.description = description;
760: }
761: }
762: }
|