001: /*
002: * TestOpenJPAEntityManager.java
003: *
004: * Created on October 12, 2006, 4:40 PM
005: *
006: * To change this template, choose Tools | Template Manager
007: * and open the template in the editor.
008: */
009: /*
010: * Licensed to the Apache Software Foundation (ASF) under one
011: * or more contributor license agreements. See the NOTICE file
012: * distributed with this work for additional information
013: * regarding copyright ownership. The ASF licenses this file
014: * to you under the Apache License, Version 2.0 (the
015: * "License"); you may not use this file except in compliance
016: * with the License. You may obtain a copy of the License at
017: *
018: * http://www.apache.org/licenses/LICENSE-2.0
019: *
020: * Unless required by applicable law or agreed to in writing,
021: * software distributed under the License is distributed on an
022: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
023: * KIND, either express or implied. See the License for the
024: * specific language governing permissions and limitations
025: * under the License.
026: */
027: package org.apache.openjpa.persistence.kernel;
028:
029: import java.io.ByteArrayInputStream;
030: import java.io.ByteArrayOutputStream;
031: import java.io.ObjectInputStream;
032: import java.io.ObjectOutputStream;
033: import java.util.ArrayList;
034: import java.util.Collection;
035: import java.util.Iterator;
036: import java.util.List;
037: import javax.persistence.EntityManagerFactory;
038: import javax.persistence.EntityNotFoundException;
039:
040: import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
041: import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
042: import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
043: import org.apache.openjpa.kernel.BrokerFactory;
044: import org.apache.openjpa.kernel.DelegatingBrokerFactory;
045: import org.apache.openjpa.kernel.PCState;
046: import org.apache.openjpa.persistence.Extent;
047: import org.apache.openjpa.persistence.JPAFacadeHelper;
048: import org.apache.openjpa.persistence.OpenJPAEntityManager;
049: import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
050: import org.apache.openjpa.util.Id;
051:
052: public class TestPersistenceManager extends BaseKernelTest {
053:
054: private int _id = 0;
055: private int _id2 = 0;
056:
057: public TestPersistenceManager(String name) {
058: super (name);
059: }
060:
061: /**
062: * Creates a new instance of TestOpenJPAEntityManager
063: */
064: public TestPersistenceManager() {
065: }
066:
067: public void setUp() throws Exception {
068: deleteAll(RuntimeTest1.class);
069: deleteAll(RuntimeTest2.class);
070:
071: OpenJPAEntityManager pm = getPM();
072: startTx(pm);
073:
074: RuntimeTest1 a = new RuntimeTest1("STRING", 10);
075: RuntimeTest2 b = new RuntimeTest2("STRING2", 11);
076: pm.persist(a);
077: pm.persist(b);
078: _id = a.getIntField();
079: _id2 = b.getIntField();
080:
081: endTx(pm);
082: endEm(pm);
083: }
084:
085: /**
086: * No-op test that can be run in name to see if the setup is working
087: * properly.
088: */
089: public void testSetup() {
090: }
091:
092: /**
093: * Tests that the PM throws Exceptions on usage attempts after it has been
094: * closed.
095: */
096: public void testClosed() {
097: OpenJPAEntityManager pm = getPM();
098: endEm(pm);
099:
100: try {
101: // this is the only method that should succeed
102: pm.isOpen();
103: } catch (RuntimeException re) {
104: fail("isClosed");
105: }
106: try {
107: pm.find(RuntimeTest1.class, _id);
108: fail("find");
109: } catch (RuntimeException re) {
110: }
111: try {
112: pm.persist(new RuntimeTest1(20));
113: fail("setUserObject");
114: } catch (RuntimeException re) {
115: }
116: try {
117: pm.setNontransactionalRead(true);
118: fail("setNontransactionalRead");
119: } catch (RuntimeException re) {
120: }
121: try {
122: // this method should fail
123: endEm(pm);
124: bug(65, null, "multiple close should not be allowed");
125: fail("multiple close should not be allowed");
126: } catch (Exception jdoe) {
127: // good: we should get an exception
128: }
129: }
130:
131: public void testMultipleCloseThreaded() throws Throwable {
132: final OpenJPAEntityManager pm = getPM();
133: final List result = new ArrayList();
134: startTx(pm);
135:
136: endEm(pm);
137:
138: new Thread() {
139: public void run() {
140: try {
141: endEm(pm);
142: result.add(new Integer(0));
143: } catch (Exception jdoe) {
144: result.add(jdoe);
145: } catch (Throwable t) {
146: result.add(t);
147: }
148: }
149: }.start();
150:
151: while (result.size() == 0)
152: Thread.currentThread().yield(); // wait for results
153: Object ret = result.get(0);
154:
155: if (ret instanceof Exception)
156: return; // good
157:
158: if (ret instanceof Throwable)
159: throw (Throwable) ret;
160:
161: bug(65, null,
162: "multiple close in different threads should not be allowed");
163: }
164:
165: /**
166: * This method tries to perform operations that should lead to
167: * illegal states, such as persisting instances outside of transactions,
168: * etc.
169: */
170: public void testIllegalState() {
171: OpenJPAEntityManager pm = getPM();
172:
173: RuntimeTest1 a = new RuntimeTest1("foo", 14);
174: RuntimeTest1 a2 = (RuntimeTest1) pm.find(RuntimeTest1.class,
175: _id);
176:
177: try {
178: pm.persist(a);
179: fail("persist");
180: } catch (Exception ise) {
181: }
182: try {
183: pm.isTransactional(a2);
184: fail("makeTransactional");
185: } catch (Exception ise) {
186: }
187: try {
188: pm.remove(a2);
189: fail("deletePersistent");
190: } catch (Exception ise) {
191: }
192:
193: endEm(pm);
194: }
195:
196: public void testOpenJPAEntityManagerFactorySerializable()
197: throws Exception {
198: OpenJPAEntityManagerFactory pmf = (OpenJPAEntityManagerFactory) getEmf();
199: assertNotNull("OpenJPAEntityManagerFactory is null.", pmf);
200:
201: ByteArrayOutputStream baos = new ByteArrayOutputStream();
202: ObjectOutputStream oos = new ObjectOutputStream(baos);
203: oos.writeObject(pmf);
204:
205: OpenJPAEntityManagerFactory pmf2 = (OpenJPAEntityManagerFactory) new ObjectInputStream(
206: new ByteArrayInputStream(baos.toByteArray()))
207: .readObject();
208: assertNotNull(
209: "Deserialized OpenJPAEntityManagerFactory is null.",
210: pmf2);
211:
212: OpenJPAEntityManager pm = pmf2.createEntityManager();
213: startTx(pm);
214: // go through some objects to make sure our PM is OK
215: for (Iterator i = pm.createExtent(RuntimeTest1.class, true)
216: .iterator(); i.hasNext(); i.next())
217: ;
218: endTx(pm);
219: endEm(pm);
220: }
221:
222: private static BrokerFactory toBrokerFactory(
223: EntityManagerFactory emf) {
224: BrokerFactory bf = JPAFacadeHelper.toBrokerFactory(emf);
225: if (bf instanceof DelegatingBrokerFactory)
226: bf = ((DelegatingBrokerFactory) bf).getInnermostDelegate();
227: return bf;
228: }
229:
230: /**
231: * Test that a getObjectById() returns the correct instance.
232: */
233: public void testGetObjectById() {
234: // test with valid id
235: OpenJPAEntityManager pm = getPM();
236: RuntimeTest1 b = (RuntimeTest1) pm
237: .find(RuntimeTest1.class, _id);
238: assertEquals("STRING", b.getStringField());
239:
240: // invalid with possible subclasses should throw immediate exception
241: Object invalidId = new Id(RuntimeTest1.class, -1L);
242: try {
243: pm.find(RuntimeTest1.class, invalidId);
244: fail("Invalid Object");
245: } catch (Exception e) {
246: }
247:
248: // invalid without subclasses and without validating should return
249: // hollow
250: invalidId = new Id(RuntimeTest4.class, -1L);
251: try {
252: RuntimeTest4 a = (RuntimeTest4) pm.getReference(
253: RuntimeTest4.class, invalidId);
254: assertNotNull(
255: "invalid without subclasses and without validating "
256: + "should return hollow or throw exception",
257: a);
258: a.getName();
259: fail("Allowed access of invalid hollow instance.");
260: } catch (EntityNotFoundException enfe) {
261: // expected
262: }
263:
264: invalidId = new Id(RuntimeTest4.class, -3L);
265: assertNull(pm.find(RuntimeTest4.class, invalidId));
266:
267: endEm(pm);
268: }
269:
270: public void testGetObjectsById() {
271: OpenJPAEntityManager pm = getPM();
272: ArrayList idlist = new ArrayList();
273: idlist.add(_id);
274: idlist.add(_id2);
275: Collection pcs = pm.findAll(RuntimeTest1.class, idlist);
276: assertEquals(2, pcs.size());
277: Iterator iter = pcs.iterator();
278: assertEquals("STRING", ((RuntimeTest1) iter.next())
279: .getStringField());
280: assertEquals("STRING2", ((RuntimeTest2) iter.next())
281: .getStringField());
282: endEm(pm);
283:
284: pm = getPM();
285: idlist = new ArrayList();
286: idlist.add(_id);
287: idlist.add(_id);
288: pcs = pm.findAll(RuntimeTest1.class, idlist);
289: iter = pcs.iterator();
290: assertEquals(2, pcs.size());
291: assertEquals("STRING", ((RuntimeTest1) iter.next())
292: .getStringField());
293: iter = pcs.iterator();
294: assertTrue(iter.next() == iter.next());
295: endEm(pm);
296:
297: // invalid id causes exception
298: Object invalidId = new Id(RuntimeTest4.class, -1L);
299: pm = getPM();
300: idlist = new ArrayList();
301: idlist.add(_id);
302: idlist.add(invalidId);
303: try {
304: pcs = (ArrayList) pm.findAll(RuntimeTest1.class, idlist);
305: iter = pcs.iterator();
306: assertEquals(2, pcs.size());
307: assertEquals("STRING", ((RuntimeTest1) iter.next())
308: .getStringField());
309: assertNotNull(iter.next());
310: fail("invalid id didnt cause exception");
311: } catch (Exception onfe) {
312: //expected exception. invalid id causes exception
313: }
314:
315: try {
316: ((RuntimeTest4) iter.next()).getName();
317: fail("Accessed invalid object.");
318: } catch (Exception onfe) {
319: bug(1138, onfe, "Wrong exception type");
320: }
321:
322: pm = getPM();
323: try {
324: pm.findAll(RuntimeTest1.class, idlist);
325: fail("Found invalid object.");
326: } catch (Exception e) {
327: }
328: endEm(pm);
329: }
330:
331: public void testEvictAll() {
332: OpenJPAEntityManager pm = getPM();
333:
334: List l = ((Extent) pm.createExtent(RuntimeTest1.class, true))
335: .list();
336: pm.retrieveAll(l);
337: for (Iterator iter = l.iterator(); iter.hasNext();) {
338: PCState s = getStateManager(iter.next(), pm).getPCState();
339: assertEquals(PCState.PNONTRANS, s);
340: }
341: pm.evictAll();
342: for (Iterator iter = l.iterator(); iter.hasNext();) {
343: PCState s = getStateManager(iter.next(), pm).getPCState();
344: assertEquals(PCState.HOLLOW, s);
345: }
346: }
347:
348: public void testEvictAllCollection() {
349: OpenJPAEntityManager pm = getPM();
350:
351: List l = ((Extent) pm.createExtent(RuntimeTest1.class, true))
352: .list();
353: pm.retrieveAll(l);
354: for (Iterator iter = l.iterator(); iter.hasNext();) {
355: PCState s = getStateManager(iter.next(), pm).getPCState();
356: assertEquals(PCState.PNONTRANS, s);
357: }
358: pm.evictAll(l);
359: for (Iterator iter = l.iterator(); iter.hasNext();) {
360: PCState s = getStateManager(iter.next(), pm).getPCState();
361: assertEquals(PCState.HOLLOW, s);
362: }
363: }
364:
365: public void testEvictAllClass() {
366: OpenJPAEntityManager pm = getPM();
367:
368: List l = ((Extent) pm.createExtent(RuntimeTest1.class, true))
369: .list();
370: pm.retrieveAll(l);
371: for (Iterator iter = l.iterator(); iter.hasNext();) {
372: PCState s = getStateManager(iter.next(), pm).getPCState();
373: assertEquals(PCState.PNONTRANS, s);
374: }
375: pm.evictAll(RuntimeTest1.class);
376: for (Iterator iter = l.iterator(); iter.hasNext();) {
377: PCState s = getStateManager(iter.next(), pm).getPCState();
378: assertEquals(PCState.HOLLOW, s);
379: }
380: }
381:
382: public void testEvictAllClassFailure() {
383: OpenJPAEntityManager pm = getPM();
384:
385: List l = ((Extent) pm.createExtent(RuntimeTest1.class, true))
386: .list();
387: pm.retrieveAll(l);
388: for (Iterator iter = l.iterator(); iter.hasNext();) {
389: PCState s = getStateManager(iter.next(), pm).getPCState();
390: assertEquals(PCState.PNONTRANS, s);
391: }
392: pm.evictAll(RuntimeTest2.class);
393: boolean foundPNONTRANS = false;
394: for (Iterator iter = l.iterator(); iter.hasNext();) {
395: PCState s = getStateManager(iter.next(), pm).getPCState();
396: if (s == PCState.PNONTRANS) {
397: foundPNONTRANS = true;
398: break;
399: }
400: }
401: assertTrue(
402: "should have found some RuntimeTest1s that were not "
403: + "evicted", foundPNONTRANS);
404: }
405:
406: public void testEvictAllExtent() {
407: OpenJPAEntityManager pm = getPM();
408:
409: List l = ((Extent) pm.createExtent(RuntimeTest1.class, true))
410: .list();
411: pm.retrieveAll(l);
412: for (Iterator iter = l.iterator(); iter.hasNext();) {
413: PCState s = getStateManager(iter.next(), pm).getPCState();
414: assertEquals(PCState.PNONTRANS, s);
415: }
416: pm.evictAll(pm.createExtent(RuntimeTest1.class, true));
417: for (Iterator iter = l.iterator(); iter.hasNext();) {
418: PCState s = getStateManager(iter.next(), pm).getPCState();
419: assertEquals(PCState.HOLLOW, s);
420: }
421:
422: pm.retrieveAll(l);
423: for (Iterator iter = l.iterator(); iter.hasNext();) {
424: PCState s = getStateManager(iter.next(), pm).getPCState();
425: assertEquals(PCState.PNONTRANS, s);
426: }
427: pm.evictAll(pm.createExtent(RuntimeTest1.class, false));
428: for (Iterator iter = l.iterator(); iter.hasNext();) {
429: Object o = iter.next();
430: if (o.getClass() == RuntimeTest1.class) {
431: PCState s = getStateManager(o, pm).getPCState();
432: assertEquals(PCState.HOLLOW, s);
433: }
434: }
435: }
436: }
|