001: /*
002: * TestClassDBSequenceFactory.java
003: *
004: * Created on October 6, 2006, 11:29 AM
005: *
006: * To change this template, choose Tools | Template Manager
007: * and open the template in the editor.
008: */
009:
010: /*
011: * Licensed to the Apache Software Foundation (ASF) under one
012: * or more contributor license agreements. See the NOTICE file
013: * distributed with this work for additional information
014: * regarding copyright ownership. The ASF licenses this file
015: * to you under the Apache License, Version 2.0 (the
016: * "License"); you may not use this file except in compliance
017: * with the License. You may obtain a copy of the License at
018: *
019: * http://www.apache.org/licenses/LICENSE-2.0
020: *
021: * Unless required by applicable law or agreed to in writing,
022: * software distributed under the License is distributed on an
023: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
024: * KIND, either express or implied. See the License for the
025: * specific language governing permissions and limitations
026: * under the License.
027: */
028: package org.apache.openjpa.persistence.jdbc.schema;
029:
030: import java.util.*;
031: import org.apache.openjpa.conf.OpenJPAConfiguration;
032: import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
033: import org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq;
034: import org.apache.openjpa.jdbc.meta.ClassMapping;
035: import org.apache.openjpa.jdbc.schema.Sequence;
036: import org.apache.openjpa.kernel.Broker;
037:
038: import org.apache.openjpa.persistence.jdbc.common.apps.*;
039:
040: import java.lang.annotation.Annotation;
041: import junit.framework.*;
042: import javax.persistence.EntityManager;
043: import javax.persistence.EntityManagerFactory;
044: import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
045: import org.apache.openjpa.persistence.OpenJPAEntityManager;
046:
047: public class TestClassDBSequenceFactory extends
048: org.apache.openjpa.persistence.jdbc.kernel.BaseJDBCTest {
049:
050: /** Creates a new instance of TestClassDBSequenceFactory */
051: public TestClassDBSequenceFactory() {
052: }
053:
054: public TestClassDBSequenceFactory(String test) {
055: super (test);
056: }
057:
058: public void setUp() {
059: deleteAll(SeqE.class);
060: }
061:
062: boolean supportsPessimisticLocking() {
063: OpenJPAConfiguration conf = getConfiguration();
064: return conf instanceof JDBCConfiguration
065: && ((JDBCConfiguration) conf).getDBDictionaryInstance().supportsSelectForUpdate;
066: }
067:
068: public void testVirtualSuperclass() {
069:
070: OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory) getEmf(getProps());
071: OpenJPAEntityManager pm = (OpenJPAEntityManager) pmf
072: .createEntityManager();
073: //FIXME jthomas
074: //Sequence gen = pm.getIdentitySequence(SeqF.class);
075: Sequence gen = null;
076: long next = ((Number) gen.getIncrement()).longValue();
077: //FIXME jthomas
078: //gen = pm.getIdentitySequence(SeqG.class);
079: assertEquals(next + 1, ((Number) gen.getIncrement())
080: .longValue());
081: pm.close();
082: pmf.close();
083: }
084:
085: public void testIgnoreVirtualSuperclass() {
086:
087: Map props = new HashMap();
088: props.put("TableName", "JDO_CLASS_SEQUENCE");
089: props.put("IgnoreVirtual", "true");
090: OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory) getEmf(props);
091: OpenJPAEntityManager pm = pmf.createEntityManager();
092: //FIXME jthomas
093: //Sequence gen = pm.getIdentitySequence(SeqF.class);
094: Sequence gen = null;
095: long next = ((Number) gen.getIncrement()).longValue();
096: //FIXME jthomas
097: //Sequence gen2 = pm.getIdentitySequence(SeqG.class);
098: Sequence gen2 = null;
099: long next2 = ((Number) gen2.getIncrement()).longValue();
100: if (next2 != next + 1)
101: return; // valid.
102: assertTrue(((Number) gen.getIncrement()).longValue() != next2 + 1);
103:
104: pm.close();
105: pmf.close();
106: }
107:
108: /**
109: * Based on reported bug case.
110: */
111: public void testNoSequenceHolesOnAttach() {
112: PerClassTestObject3 pc = new PerClassTestObject3();
113: OpenJPAEntityManager pm = (OpenJPAEntityManager) currentEntityManager();
114: startTx(pm);
115: ;
116: pm.persist(pc);
117: endTx(pm);
118: ;
119: long id1 = pc.getId();
120:
121: pc = new PerClassTestObject3();
122: startTx(pm);
123: ;
124: pm.persist(pc);
125: long id2 = pc.getId();
126: endTx(pm);
127: ;
128: pm.close();
129:
130: pc = new PerClassTestObject3();
131: pm = (OpenJPAEntityManager) currentEntityManager();
132: startTx(pm);
133: ;
134: pm.persist(pc);
135: endTx(pm);
136: ;
137: long id3 = pc.getId();
138: pm.close();
139:
140: assertEquals(id1 + 1, id2);
141: assertEquals(id2 + 1, id3);
142: }
143:
144: /**
145: * Tests that all sequence numbers are unique and in order.
146: * Will fail for dbs without pessimistic locking.
147: */
148: public void testSequence() throws Exception {
149: if (!(supportsPessimisticLocking()))
150: return;
151:
152: Set set = new HashSet();
153: JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
154: Broker broker = getBrokerFactory().newBroker();
155:
156: UpdateThread t1 = new UpdateThread(set, broker);
157: UpdateThread t2 = new UpdateThread(set, broker);
158:
159: t1.start();
160: t2.start();
161: t1.join();
162: t2.join();
163:
164: if (t1.error != null)
165: throw t1.error;
166: if (t2.error != null)
167: throw t2.error;
168:
169: assertEquals(102, set.size());
170: }
171:
172: public void testSequenceGenerator() {
173: OpenJPAEntityManager pm = (OpenJPAEntityManager) currentEntityManager();
174:
175: // make sure the sequence generator creates separate
176: // instances.
177: for (int i = 0; i < 100; i++) {
178: //FIXME jthomas
179: /*assertEquals(((Number) pm.getIdentitySequence(SeqD.class).
180: next()).longValue() + 1,
181: ((Number) pm.getIdentitySequence(SeqD.class).
182: getIncrement()).longValue());
183:
184: */
185: }
186: // make sure the sequence generate is not the same as is
187: // used elsewhere
188:
189: for (int j = 0; j < 100; j++) {
190: //FIXME
191: /*
192: assertNotEquals(new Long(((Number) pm.getIdentitySequence
193: (SeqA.class).getIncrement()).longValue() + 1),
194: pm.getIdentitySequence(SeqD.class).next());
195: */
196: }
197: }
198:
199: public static void main(String[] args) {
200: //main();
201: }
202:
203: private Map getProps() {
204: Map props = new HashMap();
205: props.put("openjpa.Sequence",
206: "db-class(TableName=JDO_CLASS_SEQUENCE");
207: return props;
208: }
209:
210: private static class UpdateThread extends Thread {
211:
212: private Set _set = null;
213: private Broker _broker = null;
214: public Exception error = null;
215:
216: public UpdateThread(Set set, Broker broker) {
217: _set = set;
218: _broker = broker;
219: }
220:
221: public void run() {
222: try {
223: ClassMapping mapping = ((JDBCConfiguration) _broker
224: .getConfiguration())
225: .getMappingRepositoryInstance().getMapping(
226: SeqD.class, null, true);
227: ClassTableJDBCSeq seq = (ClassTableJDBCSeq) _broker
228: .getIdentitySequence(mapping);
229: for (int i = 0; i < 51; i++)
230: _set.add(seq.next(_broker, mapping));
231: } catch (Exception e) {
232: error = e;
233: }
234: }
235: }
236: }
|