001: package org.apache.ojb.broker.sequence;
002:
003: import org.apache.commons.lang.SerializationUtils;
004: import org.apache.ojb.broker.metadata.ClassDescriptor;
005: import org.apache.ojb.broker.metadata.DescriptorRepository;
006: import org.apache.ojb.broker.metadata.FieldDescriptor;
007: import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
008: import org.apache.ojb.broker.metadata.MetadataManager;
009: import org.apache.ojb.broker.metadata.SequenceDescriptor;
010: import org.apache.ojb.broker.query.Criteria;
011: import org.apache.ojb.broker.query.Query;
012: import org.apache.ojb.broker.query.QueryByCriteria;
013: import org.apache.ojb.broker.util.sequence.SequenceManager;
014: import org.apache.ojb.broker.util.sequence.SequenceManagerException;
015: import org.apache.ojb.broker.util.sequence.SequenceManagerFactory;
016: import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
017: import org.apache.ojb.broker.util.sequence.SequenceManagerHighLowImpl;
018: import org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl;
019: import org.apache.ojb.broker.util.sequence.SequenceManagerSeqHiLoImpl;
020: import org.apache.ojb.broker.util.sequence.SequenceManagerStoredProcedureImpl;
021: import org.apache.ojb.broker.PersistenceBroker;
022: import org.apache.ojb.broker.PersistenceBrokerFactory;
023: import org.apache.ojb.broker.PBKey;
024: import org.apache.ojb.broker.TestHelper;
025: import org.apache.ojb.broker.PersistenceBrokerException;
026: import org.apache.ojb.broker.ObjectRepository;
027: import org.apache.ojb.broker.BookArticle;
028: import org.apache.ojb.broker.Article;
029: import org.apache.ojb.broker.CdArticle;
030: import org.apache.ojb.junit.OJBTestCase;
031:
032: import java.io.Serializable;
033: import java.util.ArrayList;
034: import java.util.Collection;
035: import java.util.Iterator;
036: import java.util.List;
037: import java.util.TreeSet;
038:
039: /**
040: * Tests to verify SequenceManager implementations - All sequence
041: * manager implementations have to pass these tests without failures.
042: * <br>
043: * Note: For the multi-threaded tests, the keys will be generated once for all tests.
044: *
045: * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
046: * @version $Id: SequenceManagerTest.java,v 1.26.4.1 2005/07/24 23:57:42 arminw Exp $
047: */
048: public class SequenceManagerTest extends OJBTestCase {
049: private static final String TEST_SEQUENCE_NAME = "TEST_SEQUENCE";
050: /**
051: * Max PK value for {@link Repository.SMMax} test class prepared
052: * in database.
053: */
054: private static final int SMMAX_MAX_PK_VALUE = 131;
055: /**
056: * Error message.
057: */
058: private static final String SMMAX_FAIL_MESSAGE = "Expected "
059: + SMMAX_MAX_PK_VALUE
060: + ", something goes wrong when try to identify max PK id in the prepared database tables"
061: + " - Check the ...SMMAX... database tables for id "
062: + SMMAX_MAX_PK_VALUE
063: + ", if id was found in one of the tables, test fails";
064:
065: private static final String DEF_FAIL_MESSAGE = "Found different max PK, expected the same";
066:
067: /*
068: attributes for the multi-threaded key generation
069: used in method generateKeys(). See test cases
070: testSequenceGeneration
071: testForLostKeys
072: */
073: private int loops = 1000;
074: private int instances = 10;
075: private Class targetClass = Repository.SMSameTableA.class;
076: // end
077:
078: private int numberOfKeys = 200;
079:
080: private PersistenceBroker[] brokers;
081: private ThreadGroup threadGroup;
082: private static ArrayList generatedKeys;
083: private static int keyCount;
084:
085: public SequenceManagerTest(String s) {
086: super (s);
087: }
088:
089: public static void main(String[] args) {
090: String[] arr = { SequenceManagerTest.class.getName() };
091: junit.textui.TestRunner.main(arr);
092: }
093:
094: protected void setUp() throws Exception {
095: super .setUp();
096: }
097:
098: protected void tearDown() throws Exception {
099: super .tearDown();
100: }
101:
102: /**
103: * Test support for classes with multiple autoincrement
104: * fields - e.g. see repository for {@link Repository.SMKey}
105: */
106: public void testMultipleAutoincrement() {
107: String MESSAGE = "Autoincrement field was not incremented: ";
108: String name = "my test key " + System.currentTimeMillis();
109: Repository.SMKey key = new Repository.SMKey();
110: key.setName(name);
111: PersistenceBroker broker = PersistenceBrokerFactory
112: .defaultPersistenceBroker();
113: broker.beginTransaction();
114: broker.store(key);
115: broker.commitTransaction();
116: assertEquals("Value was not store: " + key, name, key.getName());
117: assertNotNull(MESSAGE + key, key.getIntegerKey());
118: assertTrue(MESSAGE + key, (key.getIntKey() != 0));
119: assertNotNull(MESSAGE + key, key.getLongKey());
120: assertNotNull(MESSAGE + key, key.getStringKey());
121: // System.out.println("## SMKey: \n"+key);
122:
123: Criteria cr = new Criteria();
124: cr.addEqualTo("name", name);
125: Query query = new QueryByCriteria(Repository.SMKey.class, cr);
126: key = (Repository.SMKey) broker.getObjectByQuery(query);
127:
128: assertEquals("Value was not store: ", name, key.getName());
129: assertNotNull(MESSAGE + key, key.getIntegerKey());
130: assertTrue(MESSAGE + key, (key.getIntKey() != 0));
131: assertNotNull(MESSAGE + key, key.getLongKey());
132: assertNotNull(MESSAGE + key, key.getStringKey());
133: // System.out.println("## SMKey: \n"+key);
134:
135: broker.close();
136: }
137:
138: /**
139: * Test the use of the 'sequence-name' field descriptor
140: * attribute.
141: */
142: public void testSequenceNameAttribute() throws Exception {
143: // sequence name used in the repository
144: String fieldName = "stringKey";
145: PersistenceBroker broker = PersistenceBrokerFactory
146: .defaultPersistenceBroker();
147: FieldDescriptor field = broker.getClassDescriptor(
148: Repository.SMKey.class).getFieldDescriptorByName(
149: fieldName);
150: String result = SequenceManagerHelper.buildSequenceName(broker,
151: field, true);
152:
153: assertEquals(TEST_SEQUENCE_NAME, result);
154: broker.close();
155: }
156:
157: public void testAutoNaming() throws Exception {
158: String jcdAlias = "testAutoNaming";
159: PBKey tempKey = new PBKey(jcdAlias, TestHelper.DEF_KEY
160: .getUser(), TestHelper.DEF_KEY.getPassword());
161: MetadataManager mm = MetadataManager.getInstance();
162: PersistenceBroker broker = null;
163: try {
164: JdbcConnectionDescriptor jcd = mm.connectionRepository()
165: .getDescriptor(TestHelper.DEF_KEY);
166: jcd = (JdbcConnectionDescriptor) SerializationUtils
167: .clone(jcd);
168: // modify jcd copy
169: jcd.setJcdAlias(jcdAlias);
170: SequenceDescriptor sd = jcd.getSequenceDescriptor();
171: assertNotNull(
172: "Can not find sequence-descriptor - check test", sd);
173: // don't use autoNaming
174: sd.addAttribute("autoNaming", "false");
175: // add new connection descriptor to global base
176: mm.connectionRepository().addDescriptor(jcd);
177:
178: // allow per thread changes of persistent object data
179: mm.setEnablePerThreadChanges(true);
180: DescriptorRepository dr = mm.copyOfGlobalRepository();
181: ClassDescriptor cld = dr
182: .getDescriptorFor(SMAutoNaming.class);
183: FieldDescriptor field = cld.getAutoIncrementFields()[0];
184:
185: // set sequence name for persistent object to null
186: field.setSequenceName(null);
187: mm.setDescriptor(dr);
188:
189: broker = PersistenceBrokerFactory
190: .createPersistenceBroker(tempKey);
191: try {
192: /*
193: persistent object descriptor doesn't has a sequence name
194: and autoNaming is false --> expect an exception
195: */
196: SMAutoNaming obj = new SMAutoNaming("testAutoNaming_1");
197: sd = broker.serviceConnectionManager()
198: .getConnectionDescriptor()
199: .getSequenceDescriptor();
200: assertTrue("false"
201: .equals(sd.getAttribute("autoNaming")));
202:
203: broker.beginTransaction();
204: broker.store(obj);
205: broker.commitTransaction();
206: fail("If sequence manager implementation supports 'autoNaming' feature,"
207: + " this test should cause an exception (else ignore this failure).");
208: } catch (PersistenceBrokerException e) {
209: assertTrue(true);
210: broker.abortTransaction();
211: }
212:
213: try {
214: /* attribute 'auto-naming' is still false,
215: but now we set a sequence name for autoincrement field
216: --> should pass
217: */
218: field.setSequenceName("AA_testAutoNaming_user_set");
219: SMAutoNaming obj = new SMAutoNaming("testAutoNaming_2");
220: broker.beginTransaction();
221: broker.store(obj);
222: broker.commitTransaction();
223: } catch (PersistenceBrokerException e) {
224: e.printStackTrace();
225: broker.close();
226: throw e;
227: }
228:
229: try {
230: // let OJB re-initialize sequence-manager
231: broker.close();
232: PersistenceBrokerFactory.releaseAllInstances();
233: /*
234: remove sequence name of autoincrement field
235: but enable automatic sequence name generation
236: --> should pass
237: */
238: field.setSequenceName(null);
239: sd.addAttribute("autoNaming", "true");
240: broker = PersistenceBrokerFactory
241: .createPersistenceBroker(tempKey);
242: SMAutoNaming obj = new SMAutoNaming("testAutoNaming_3");
243: broker.beginTransaction();
244: broker.store(obj);
245: broker.commitTransaction();
246: } catch (PersistenceBrokerException e) {
247: e.printStackTrace();
248: fail("Sequence key generation failed");
249: }
250:
251: } finally {
252: // cleanup
253: if (broker != null)
254: broker.close();
255: mm.setEnablePerThreadChanges(false);
256: }
257: }
258:
259: /**
260: * This test only works, when using
261: * {@link org.apache.ojb.broker.util.sequence.SequenceManagerNextValImpl}
262: * for sequence generation.
263: */
264: public void testDatabaseSequenceGeneration() throws Exception {
265: PersistenceBroker broker = PersistenceBrokerFactory
266: .defaultPersistenceBroker();
267: SequenceManager sm = SequenceManagerFactory
268: .getSequenceManager(broker);
269: if (!(sm instanceof SequenceManagerNextValImpl)) {
270: System.out
271: .println("This test only works for SeqMan implementations using "
272: + SequenceManagerNextValImpl.class
273: + " Skip test case.");
274: broker.close();
275: return;
276: }
277: int count = 0;
278: FieldDescriptor idFld = broker.getClassDescriptor(
279: Repository.SMDatabaseSequence.class)
280: .getAutoIncrementFields()[0];
281: for (int i = 0; i < 10; i++) {
282: Integer val = (Integer) sm.getUniqueValue(idFld);
283: count += val.intValue();
284: System.err.println("count " + count);
285: }
286: assertFalse("No keys generated", count == 0);
287: broker.close();
288: }
289:
290: /**
291: * Test the max id search used in the standard sequence manager
292: * implementations.
293: */
294: public void testMaxKeySearch1() {
295: PersistenceBroker broker = PersistenceBrokerFactory
296: .defaultPersistenceBroker();
297: FieldDescriptor field = null;
298:
299: // find max from classes using different tables
300: // FieldDescriptor field = broker.getClassDescriptor(Repository.SMMax.class).getAutoIncrementFields()[0];
301: // long result1 = SequenceManagerHelper.getMaxForExtent(broker, field);
302: field = broker.getClassDescriptor(Repository.SMMaxA.class)
303: .getAutoIncrementFields()[0];
304: long result2 = SequenceManagerHelper.getMaxForExtent(broker,
305: field);
306: field = broker.getClassDescriptor(Repository.SMMaxAA.class)
307: .getAutoIncrementFields()[0];
308: long result3 = SequenceManagerHelper.getMaxForExtent(broker,
309: field);
310: field = broker.getClassDescriptor(Repository.SMMaxAB.class)
311: .getAutoIncrementFields()[0];
312: long result4 = SequenceManagerHelper.getMaxForExtent(broker,
313: field);
314: field = broker.getClassDescriptor(Repository.SMMaxAAA.class)
315: .getAutoIncrementFields()[0];
316: long result5 = SequenceManagerHelper.getMaxForExtent(broker,
317: field);
318:
319: // assertEquals(SMMAX_FAIL_MESSAGE, SMMAX_MAX_PK_VALUE, result1);
320: assertEquals(SMMAX_FAIL_MESSAGE, SMMAX_MAX_PK_VALUE, result2);
321: assertEquals(SMMAX_FAIL_MESSAGE, SMMAX_MAX_PK_VALUE, result3);
322: assertEquals(SMMAX_FAIL_MESSAGE, SMMAX_MAX_PK_VALUE, result4);
323: assertEquals(SMMAX_FAIL_MESSAGE, SMMAX_MAX_PK_VALUE, result5);
324:
325: broker.close();
326: }
327:
328: /**
329: * Test the max id search used in the standard sequence manager
330: * implementations.
331: */
332: public void testMaxKeySearch2() {
333: PersistenceBroker broker = PersistenceBrokerFactory
334: .defaultPersistenceBroker();
335: // find max from classes using the same table
336: broker.beginTransaction();
337: broker.store(new ObjectRepository.A());
338: broker.store(new ObjectRepository.B());
339: broker.store(new ObjectRepository.B1());
340: broker.store(new ObjectRepository.C());
341: broker.store(new ObjectRepository.D());
342: broker.commitTransaction();
343: long[] result = new long[5];
344: FieldDescriptor field = broker.getClassDescriptor(
345: ObjectRepository.A.class).getAutoIncrementFields()[0];
346: result[0] = SequenceManagerHelper
347: .getMaxForExtent(broker, field);
348: field = broker.getClassDescriptor(ObjectRepository.B.class)
349: .getAutoIncrementFields()[0];
350: result[1] = SequenceManagerHelper
351: .getMaxForExtent(broker, field);
352: field = broker.getClassDescriptor(ObjectRepository.C.class)
353: .getAutoIncrementFields()[0];
354: result[2] = SequenceManagerHelper
355: .getMaxForExtent(broker, field);
356: field = broker.getClassDescriptor(ObjectRepository.D.class)
357: .getAutoIncrementFields()[0];
358: result[3] = SequenceManagerHelper
359: .getMaxForExtent(broker, field);
360: field = broker.getClassDescriptor(ObjectRepository.B1.class)
361: .getAutoIncrementFields()[0];
362: result[4] = SequenceManagerHelper
363: .getMaxForExtent(broker, field);
364: broker.close();
365:
366: for (int i = 0; i < result.length; i++) {
367: for (int k = 0; k < result.length; k++) {
368: if (!(result[i] == result[k])) {
369: fail(DEF_FAIL_MESSAGE);
370: }
371: }
372: }
373: }
374:
375: /**
376: * Test the max id search used in the standard sequence manager
377: * implementations.
378: */
379: public void testMaxKeySearch3() {
380: PersistenceBroker broker = PersistenceBrokerFactory
381: .defaultPersistenceBroker();
382: long[] result = new long[3];
383: FieldDescriptor field = broker
384: .getClassDescriptor(Article.class)
385: .getAutoIncrementFields()[0];
386: result[0] = SequenceManagerHelper
387: .getMaxForExtent(broker, field);
388: // field = broker.getClassDescriptor(AbstractArticle.class).getAutoIncrementFields()[0];
389: // result[1] = SequenceManagerHelper.getMaxForExtent(broker, field);
390: field = broker.getClassDescriptor(BookArticle.class)
391: .getAutoIncrementFields()[0];
392: result[1] = SequenceManagerHelper
393: .getMaxForExtent(broker, field);
394: // field = broker.getClassDescriptor(AbstractCdArticle.class).getAutoIncrementFields()[0];
395: // result[2] = SequenceManagerHelper.getMaxForExtent(broker, field);
396: field = broker.getClassDescriptor(CdArticle.class)
397: .getAutoIncrementFields()[0];
398: result[2] = SequenceManagerHelper
399: .getMaxForExtent(broker, field);
400: broker.close();
401:
402: for (int i = 0; i < result.length; i++) {
403: for (int k = 0; k < result.length; k++) {
404: if (!(result[i] == result[k])) {
405: fail(DEF_FAIL_MESSAGE);
406: }
407: }
408: }
409: }
410:
411: /**
412: * Tests if the generated id's are unique across extents.
413: */
414: public void testUniqueAcrossExtendsWithDifferentTables1()
415: throws Exception {
416: Class classOne = Repository.SMInterfaceExtendAAA.class;
417: Class classTwo = Repository.SMInterfaceExtendBB.class;
418: doKeyAnalysing(classOne, classTwo);
419: }
420:
421: /**
422: * Tests if the generated id's are unique across extents.
423: */
424: public void testUniqueAcrossExtendsWithDifferentTables2()
425: throws Exception {
426: Class classOne = Repository.SMInterfaceExtendAA.class;
427: Class classTwo = Repository.SMInterfaceExtendB.class;
428: doKeyAnalysing(classOne, classTwo);
429: }
430:
431: /**
432: * Tests if the generated id's are unique across extents.
433: */
434: public void testUniqueAcrossExtendsWithDifferentTables3()
435: throws Exception {
436: Class classOne = Repository.SMInterfaceExtendA.class;
437: Class classTwo = Repository.SMInterfaceExtendAB.class;
438: doKeyAnalysing(classOne, classTwo);
439: }
440:
441: /**
442: * Tests if the generated id's are unique across extents.
443: */
444: public void testUniqueAcrossExtendsWithSameTable1()
445: throws Exception {
446: Class classOne = Repository.SMSameTableAA.class;
447: Class classTwo = Repository.SMSameTableBB.class;
448: doKeyAnalysing(classOne, classTwo);
449: }
450:
451: /**
452: * Tests if the generated id's are unique across extents.
453: */
454: public void testUniqueAcrossExtendsWithSameTable3()
455: throws Exception {
456: Class classOne = Repository.SMSameTableA.class;
457: Class classTwo = Repository.SMSameTableB.class;
458: doKeyAnalysing(classOne, classTwo);
459: }
460:
461: /**
462: * Tests if the generated id's are unique across extents.
463: */
464: public void testUniqueAcrossExtendsWithSameTable4()
465: throws Exception {
466: Class classOne = ObjectRepository.A.class;
467: Class classTwo = ObjectRepository.B.class;
468: doKeyAnalysing(classOne, classTwo);
469: }
470:
471: /**
472: * Tests if the generated id's are unique across extents.
473: */
474: public void testUniqueAcrossExtendsWithSameTable5()
475: throws Exception {
476: Class classOne = ObjectRepository.B1.class;
477: Class classTwo = ObjectRepository.C.class;
478: doKeyAnalysing(classOne, classTwo);
479: }
480:
481: private void doKeyAnalysing(Class classOne, Class classTwo)
482: throws SequenceManagerException {
483: PersistenceBroker broker = PersistenceBrokerFactory
484: .defaultPersistenceBroker();
485: FieldDescriptor fieldOne = broker.getClassDescriptor(classOne)
486: .getAutoIncrementFields()[0];
487: FieldDescriptor fieldTwo = broker.getClassDescriptor(classOne)
488: .getAutoIncrementFields()[0];
489:
490: List listOne = createKeyList(broker, fieldOne, numberOfKeys);
491: List listTwo = createKeyList(broker, fieldTwo, numberOfKeys);
492: for (int i = 0; i < listOne.size(); i++) {
493: if (listTwo.contains(listOne.get(i))) {
494: fail("\nFound double generated key " + listOne.get(i)
495: + " when generate keys for \n" + classOne
496: + " with autoincrement field " + fieldOne
497: + " and \n" + classTwo
498: + " with autoincrement field " + fieldTwo);
499: }
500: }
501: broker.close();
502: }
503:
504: private List createKeyList(PersistenceBroker broker,
505: FieldDescriptor field, int number)
506: throws SequenceManagerException {
507: SequenceManager sm = SequenceManagerFactory
508: .getSequenceManager(broker);
509: List resultList = new ArrayList();
510: int result;
511: for (int i = 0; i < number; i++) {
512: Integer val = (Integer) sm.getUniqueValue(field);
513: result = val.intValue();
514: resultList.add(new Integer(result));
515: }
516: return resultList;
517: }
518:
519: /**
520: * test case written by a user
521: */
522: public void testGetUniqueIdWithOneBroker() throws Exception {
523: PersistenceBroker pb = PersistenceBrokerFactory
524: .defaultPersistenceBroker();
525: FieldDescriptor field = pb.getClassDescriptor(targetClass)
526: .getAutoIncrementFields()[0];
527: Integer val = (Integer) pb.serviceSequenceManager()
528: .getUniqueValue(field);
529: int id1 = val.intValue();
530: val = (Integer) pb.serviceSequenceManager().getUniqueValue(
531: field);
532: int id2 = val.intValue();
533: assertTrue(id1 != id2);
534: assertTrue(id2 > id1);
535: assertTrue(
536: "If the sequence manger implementation does not support continuous key generation"
537: + " per PB instance, you could ignore this failure",
538: (id2 - id1) == 1);
539: }
540:
541: /**
542: * Tests the generation of unique sequence numbers
543: * in multi-threaded environment.
544: */
545: public void testSequenceGeneration() {
546: long time = System.currentTimeMillis();
547: generateKeys();
548: time = System.currentTimeMillis() - time;
549: System.out.println(this .getClass().getName() + ": " + time
550: + " (ms) time for key generating");
551: analyseUniqueness(generatedKeys);
552: }
553:
554: /**
555: * Tests to detect the lost of sequence numbers
556: * in multi-threaded environments.
557: */
558: public void testForLostKeys() {
559: generateKeys();
560: TreeSet set = new TreeSet((List) generatedKeys.clone());
561: if (set.isEmpty())
562: fail("No generated keys found");
563: int result = ((Integer) set.last()).intValue()
564: - ((Integer) set.first()).intValue() + 1;
565: assertEquals(
566: "Sequence manager lost sequence numbers, this could be a failure or could be"
567: + " the volitional behaviour of the sequence manager"
568: + " - retry test case, check test case, check sequence manager implementation.",
569: keyCount, result);
570: }
571:
572: /**
573: * Test for unique **continuous** key generation
574: * across different PB instances.
575: *
576: * test case was written by a user - thanks.
577: * this test was *commented out* by default, because
578: * not all sequence manager implementations generate continuous keys
579: * across different PB instances.
580: */
581: public void YYYtest_getUniqueIdWithTwoBrokers() throws Exception {
582: PersistenceBroker pb = PersistenceBrokerFactory
583: .defaultPersistenceBroker();
584: PersistenceBroker pb2 = PersistenceBrokerFactory
585: .defaultPersistenceBroker();
586: FieldDescriptor field = pb.getClassDescriptor(targetClass)
587: .getAutoIncrementFields()[0];
588:
589: Integer val = (Integer) pb.serviceSequenceManager()
590: .getUniqueValue(field);
591: int id1 = val.intValue();
592:
593: val = (Integer) pb2.serviceSequenceManager().getUniqueValue(
594: field);
595: int id2 = val.intValue();
596:
597: assertTrue(id1 != id2);
598: assertTrue(id2 > id1);
599: assertTrue((id2 - id1) == 1);
600:
601: val = (Integer) pb2.serviceSequenceManager().getUniqueValue(
602: field);
603: id1 = val.intValue();
604:
605: val = (Integer) pb.serviceSequenceManager().getUniqueValue(
606: field);
607: id2 = val.intValue();
608:
609: assertTrue(id1 != id2);
610: assertTrue(id2 > id1);
611: assertTrue((id2 - id1) == 1);
612:
613: val = (Integer) pb.serviceSequenceManager().getUniqueValue(
614: field);
615: id1 = val.intValue();
616:
617: val = (Integer) pb2.serviceSequenceManager().getUniqueValue(
618: field);
619: id2 = val.intValue();
620:
621: assertTrue(id1 != id2);
622: assertTrue(id2 > id1);
623: assertTrue((id2 - id1) == 1);
624: }
625:
626: /**
627: * Test case for internal use while developing!
628: * Was commented out by default!
629: */
630: public void YYYtestSequenceManagerStoredProcedureImpl()
631: throws Exception {
632: JdbcConnectionDescriptor jcd = MetadataManager.getInstance()
633: .connectionRepository().getDescriptor(
634: PersistenceBrokerFactory.getDefaultKey());
635: SequenceDescriptor old_sd = (SequenceDescriptor) SerializationUtils
636: .clone(jcd.getSequenceDescriptor());
637: PersistenceBroker broker;
638: try {
639: jcd.setSequenceDescriptor(new SequenceDescriptor(jcd,
640: SequenceManagerStoredProcedureImpl.class));
641: PersistenceBrokerFactory.releaseAllInstances();
642: broker = PersistenceBrokerFactory
643: .defaultPersistenceBroker();
644: SequenceManager sm = broker.serviceSequenceManager();
645: if (!(sm instanceof SequenceManagerStoredProcedureImpl)) {
646: fail("testSM_StoredProcedure: Expected sequence manager implemenation was "
647: + SequenceManagerStoredProcedureImpl.class
648: .getName());
649: return;
650: }
651: // now we start the tests
652: FieldDescriptor field = broker.getClassDescriptor(
653: targetClass).getAutoIncrementFields()[0];
654: sm.getUniqueValue(field);
655:
656: generatedKeys.clear();
657: // comment in
658: // testSequenceGeneration();
659: // testMultipleAutoincrement();
660: // testSequenceNameAttribute();
661: broker.close();
662: } finally {
663: if (old_sd != null) {
664:
665: PersistenceBrokerFactory.releaseAllInstances();
666: jcd.setSequenceDescriptor(old_sd);
667: }
668: }
669: }
670:
671: private void generateKeys() {
672: // we generate the keys only once
673: if (generatedKeys != null && generatedKeys.size() > 1)
674: return;
675:
676: prepareKeyGeneration();
677:
678: System.out.println(this .getClass().getName() + ":\n"
679: + instances + " threads generating " + loops
680: + " keys per thread,\nusing target class "
681: + targetClass);
682: keyCount = 0;
683: for (int i = 0; i < instances; i++) {
684: SequenceManagerHandle handle = new SequenceManagerHandle(
685: brokers[i], targetClass, loops);
686: new Thread(threadGroup, handle).start();
687: }
688: while (threadGroup.activeCount() > 0) {
689: try {
690: Thread.sleep(300);
691: //System.out.print(".");
692: } catch (InterruptedException e) {
693: }
694: }
695:
696: cleanupKeyGeneration();
697:
698: System.out.println("Generated keys: "
699: + (generatedKeys != null ? "" + generatedKeys.size()
700: : "no keys generated"));
701: }
702:
703: private void cleanupKeyGeneration() {
704: if (brokers != null) {
705: for (int i = 0; i < instances; i++) {
706: brokers[i].close();
707: }
708: }
709: threadGroup = null;
710: brokers = null;
711: }
712:
713: private void prepareKeyGeneration() {
714: if (generatedKeys == null)
715: generatedKeys = new ArrayList();
716: PersistenceBroker broker = PersistenceBrokerFactory
717: .defaultPersistenceBroker();
718: SequenceManager sm = broker.serviceSequenceManager();
719: int seqGrabSize = 0;
720: // we need the SM grab size
721: if (sm instanceof SequenceManagerSeqHiLoImpl
722: || sm instanceof SequenceManagerHighLowImpl) {
723: SequenceDescriptor sd = broker.serviceConnectionManager()
724: .getConnectionDescriptor().getSequenceDescriptor();
725: String strSize = sd
726: .getAttribute(SequenceManagerHighLowImpl.PROPERTY_GRAB_SIZE);
727: if (strSize != null) {
728: seqGrabSize = new Integer(strSize).intValue();
729: }
730: }
731: broker.close();
732:
733: // the grab size have to be a factor of the loops number
734: // to pass the 'testForLostKeys' test because we
735: if (loops < seqGrabSize)
736: loops = seqGrabSize;
737: if (seqGrabSize != 0)
738: loops = (loops / seqGrabSize) * seqGrabSize;
739:
740: brokers = new PersistenceBroker[instances];
741: for (int i = 0; i < instances; i++) {
742: brokers[i] = PersistenceBrokerFactory
743: .defaultPersistenceBroker();
744: }
745: threadGroup = new ThreadGroup("sequenceManagerTG");
746: }
747:
748: private void analyseUniqueness(ArrayList results) {
749: System.out.println(this .getClass().getName()
750: + ": Analyse generated keys");
751: TreeSet set = new TreeSet();
752: //only to test the test
753: //set.add(new Integer(41001));
754: Iterator it = ((List) results.clone()).iterator();
755: Integer key;
756: while (it.hasNext()) {
757: key = (Integer) it.next();
758: if (set.contains(key)) {
759: fail("Found double generated key: "
760: + key
761: + ". Check the used SequenceManager implementation");
762: }
763: set.add(key);
764: }
765: System.out.println(this .getClass().getName()
766: + ": Last generated key was "
767: + ((set.size() > 0) ? set.last()
768: : " no generated keys found"));
769: set.clear();
770: }
771:
772: protected static synchronized void addResultList(List resultList) {
773: System.out.println(" add " + resultList.size()
774: + "generated Keys");
775: if (resultList == null)
776: return;
777: generatedKeys.addAll(resultList);
778: }
779:
780: protected static synchronized void countKey() {
781: ++keyCount;
782: }
783:
784: public void testObjectsFromAbstractBaseClass1() throws Exception {
785: PersistenceBroker broker = PersistenceBrokerFactory
786: .defaultPersistenceBroker();
787: try {
788: SequenceManager sm = broker.serviceSequenceManager();
789: FieldDescriptor fld_1 = broker.getClassDescriptor(
790: SMObjectOne.class).getAutoIncrementFields()[0];
791: FieldDescriptor fld_2 = broker.getClassDescriptor(
792: SMObjectTwo.class).getAutoIncrementFields()[0];
793:
794: Object result_1 = sm.getUniqueValue(fld_1);
795: Object result_2 = sm.getUniqueValue(fld_2);
796:
797: assertNotNull(result_1);
798: assertNotNull(result_2);
799: assertTrue(result_1 instanceof Integer);
800: assertTrue(result_2 instanceof Integer);
801:
802: result_1 = sm.getUniqueValue(fld_1);
803: result_2 = sm.getUniqueValue(fld_2);
804:
805: assertNotNull(result_1);
806: assertNotNull(result_2);
807: assertTrue(result_1 instanceof Integer);
808: assertTrue(result_2 instanceof Integer);
809:
810: assertFalse("Should not have same ids", result_2
811: .equals(result_1));
812: } finally {
813: if (broker != null)
814: broker.close();
815: }
816: }
817:
818: public void testObjectsFromAbstractBaseClass2() throws Exception {
819: long stamp = System.currentTimeMillis();
820: String objectName_One = "testObjectsFromAbstractBaseClass2_objOne_"
821: + stamp;
822: String objectName_Two = "testObjectsFromAbstractBaseClass2_objTwo_"
823: + stamp;
824:
825: PersistenceBroker broker = PersistenceBrokerFactory
826: .defaultPersistenceBroker();
827:
828: Repository.SMSameTableBB dummy1 = new Repository.SMSameTableBB();
829: Repository.SMInterfaceExtendA dummy2 = new Repository.SMInterfaceExtendA();
830:
831: SMObjectOne smOne_1 = new SMObjectOne(objectName_One);
832: SMObjectOne smOne_2 = new SMObjectOne(objectName_One);
833:
834: SMObjectTwo smTwo_2 = new SMObjectTwo(objectName_Two);
835: SMObjectTwo smTwo_1 = new SMObjectTwo(objectName_Two);
836: try {
837: broker.beginTransaction();
838:
839: broker.store(dummy1);
840: broker.store(dummy2);
841:
842: broker.store(smOne_1);
843: broker.store(smOne_2);
844: // broker.clearCache();
845: broker.store(smTwo_2);
846: broker.store(smTwo_1);
847:
848: broker.commitTransaction();
849:
850: // now check if store was successful
851: broker.clearCache();
852:
853: Criteria cr = new Criteria();
854: cr.addEqualTo("name", objectName_One);
855: Query query = new QueryByCriteria(SMObjectOne.class, cr);
856: Collection result = broker.getCollectionByQuery(query);
857:
858: broker.clearCache();
859:
860: Criteria cr_2 = new Criteria();
861: cr_2.addEqualTo("name", objectName_Two);
862: Query query_2 = new QueryByCriteria(SMObjectTwo.class, cr_2);
863: Collection result_2 = broker.getCollectionByQuery(query_2);
864:
865: assertEquals("We have to found 2 SMObjectOne objects", 2,
866: result.size());
867: assertEquals("We have to found 2 SMObjectTwo objects", 2,
868: result_2.size());
869: } finally {
870: if (broker != null)
871: broker.close();
872: }
873: }
874:
875: public void testMassStoreOfObjects() {
876: int outerLoops = 10;
877: int innerLoops = 30;
878: String name = "Name_" + System.currentTimeMillis();
879:
880: Repository.SMKey key = null;
881: for (int i = outerLoops - 1; i >= 0; i--) {
882: PersistenceBroker broker = PersistenceBrokerFactory
883: .defaultPersistenceBroker();
884: try {
885: broker.beginTransaction();
886: for (int j = innerLoops - 1; j >= 0; j--) {
887: key = new Repository.SMKey();
888: key.setName(name);
889: broker.store(key);
890: }
891: broker.commitTransaction();
892: } finally {
893: if (broker != null)
894: broker.close();
895: }
896: }
897: }
898:
899: // ******************************************************************************
900: // inner class
901: // ******************************************************************************
902: public static class AbstractSMObject implements Serializable {
903: private Integer objectId;
904:
905: public Integer getObjectId() {
906: return objectId;
907: }
908:
909: public void setObjectId(Integer objectId) {
910: this .objectId = objectId;
911: }
912: }
913:
914: public static class SMObjectOne extends AbstractSMObject {
915: private String name;
916:
917: public SMObjectOne() {
918: }
919:
920: public SMObjectOne(String name) {
921: this .name = name;
922: }
923:
924: public String getName() {
925: return name;
926: }
927:
928: public void setName(String name) {
929: this .name = name;
930: }
931: }
932:
933: public static class SMObjectTwo extends AbstractSMObject {
934: private String name;
935:
936: public SMObjectTwo() {
937: }
938:
939: public SMObjectTwo(String name) {
940: this .name = name;
941: }
942:
943: public String getName() {
944: return name;
945: }
946:
947: public void setName(String name) {
948: this .name = name;
949: }
950: }
951:
952: public static class SMAutoNaming extends AbstractSMObject {
953: private String name;
954:
955: public SMAutoNaming() {
956: }
957:
958: public SMAutoNaming(String name) {
959: this .name = name;
960: }
961:
962: public String getName() {
963: return name;
964: }
965:
966: public void setName(String name) {
967: this.name = name;
968: }
969: }
970:
971: }
|