blob: cfa667ee99e35884799f214c1efd66308c7f65be [file] [log] [blame]
/*
* TestOpenJPAEntityManager.java
*
* Created on October 12, 2006, 4:40 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.kernel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityNotFoundException;
import org.apache.openjpa.kernel.BrokerFactory;
import org.apache.openjpa.kernel.DelegatingBrokerFactory;
import org.apache.openjpa.kernel.PCState;
import org.apache.openjpa.persistence.Extent;
import org.apache.openjpa.persistence.JPAFacadeHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest1;
import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest2;
import org.apache.openjpa.persistence.kernel.common.apps.RuntimeTest4;
import org.apache.openjpa.util.Id;
public class TestPersistenceManager extends BaseKernelTest {
private int _id = 0;
private int _id2 = 0;
public TestPersistenceManager(String name) {
super(name);
}
/**
* Creates a new instance of TestOpenJPAEntityManager
*/
public TestPersistenceManager() {
}
@Override
public void setUp() throws Exception {
deleteAll(RuntimeTest1.class);
deleteAll(RuntimeTest2.class);
OpenJPAEntityManager pm = getPM();
startTx(pm);
RuntimeTest1 a = new RuntimeTest1("STRING", 10);
RuntimeTest2 b = new RuntimeTest2("STRING2", 11);
pm.persist(a);
pm.persist(b);
_id = a.getIntField();
_id2 = b.getIntField();
endTx(pm);
endEm(pm);
}
/**
* No-op test that can be run in name to see if the setup is working
* properly.
*/
public void testSetup() {
}
/**
* Tests that the PM throws Exceptions on usage attempts after it has been
* closed.
*/
public void testClosed() {
OpenJPAEntityManager pm = getPM();
endEm(pm);
try {
// this is the only method that should succeed
pm.isOpen();
} catch (RuntimeException re) {
fail("isClosed");
}
try {
pm.find(RuntimeTest1.class, _id);
fail("find");
} catch (RuntimeException re) {
}
try {
pm.persist(new RuntimeTest1(20));
fail("setUserObject");
} catch (RuntimeException re) {
}
try {
pm.setNontransactionalRead(true);
fail("setNontransactionalRead");
} catch (RuntimeException re) {
}
try {
// this method should fail
endEm(pm);
bug(65, null, "multiple close should not be allowed");
fail("multiple close should not be allowed");
} catch (Exception jdoe) {
// good: we should get an exception
}
}
public void testMultipleCloseThreaded()
throws Throwable {
final OpenJPAEntityManager pm = getPM();
final List result = new ArrayList();
startTx(pm);
endEm(pm);
new Thread() {
@Override
public void run() {
try {
endEm(pm);
result.add(0);
} catch (Exception jdoe) {
result.add(jdoe);
} catch (Throwable t) {
result.add(t);
}
}
}.start();
while (result.size() == 0)
{
Thread.currentThread();
Thread.yield(); // wait for results
}
Object ret = result.get(0);
if (ret instanceof Exception)
return; // good
if (ret instanceof Throwable)
throw (Throwable) ret;
bug(65, null,
"multiple close in different threads should not be allowed");
}
/**
* This method tries to perform operations that should lead to
* illegal states, such as persisting instances outside of transactions,
* etc.
*/
public void testIllegalState() {
OpenJPAEntityManager pm = getPM();
RuntimeTest1 a = new RuntimeTest1("foo", 14);
RuntimeTest1 a2 = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
try {
pm.persist(a);
fail("persist");
}
catch (Exception ise) {
}
try {
pm.isTransactional(a2);
fail("makeTransactional");
}
catch (Exception ise) {
}
try {
pm.remove(a2);
fail("deletePersistent");
}
catch (Exception ise) {
}
endEm(pm);
}
public void testOpenJPAEntityManagerFactorySerializable()
throws Exception {
OpenJPAEntityManagerFactory pmf =
(OpenJPAEntityManagerFactory) getEmf();
assertNotNull("OpenJPAEntityManagerFactory is null.", pmf);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(pmf);
OpenJPAEntityManagerFactory pmf2 = (OpenJPAEntityManagerFactory)
new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray())).readObject();
assertNotNull("Deserialized OpenJPAEntityManagerFactory is null.",
pmf2);
OpenJPAEntityManager pm = pmf2.createEntityManager();
startTx(pm);
// go through some objects to make sure our PM is OK
for (Iterator i = pm.createExtent(RuntimeTest1.class, true).iterator();
i.hasNext(); i.next())
;
endTx(pm);
endEm(pm);
}
private static BrokerFactory toBrokerFactory(EntityManagerFactory emf) {
BrokerFactory bf = JPAFacadeHelper.toBrokerFactory(emf);
if (bf instanceof DelegatingBrokerFactory)
bf = ((DelegatingBrokerFactory) bf).getInnermostDelegate();
return bf;
}
/**
* Test that a getObjectById() returns the correct instance.
*/
public void testGetObjectById() {
// test with valid id
OpenJPAEntityManager pm = getPM();
RuntimeTest1 b = (RuntimeTest1) pm.find(RuntimeTest1.class, _id);
assertEquals("STRING", b.getStringField());
// invalid with possible subclasses should throw immediate exception
Object invalidId = new Id(RuntimeTest1.class, -1L);
try {
pm.find(RuntimeTest1.class, invalidId);
fail("Invalid Object");
} catch (Exception e) {
}
// invalid without subclasses and without validating should return
// hollow
invalidId = new Id(RuntimeTest4.class, -1L);
try {
RuntimeTest4 a = (RuntimeTest4) pm.getReference(RuntimeTest4.class,
invalidId);
assertNotNull("invalid without subclasses and without validating "
+ "should return hollow or throw exception", a);
a.getName();
fail("Allowed access of invalid hollow instance.");
}
catch (EntityNotFoundException enfe) {
// expected
}
invalidId = new Id(RuntimeTest4.class, -3L);
assertNull(pm.find(RuntimeTest4.class, invalidId));
endEm(pm);
}
public void testGetObjectsById() {
OpenJPAEntityManager pm = getPM();
ArrayList idlist = new ArrayList();
idlist.add(_id);
idlist.add(_id2);
Collection pcs = pm.findAll(RuntimeTest1.class, idlist);
assertEquals(2, pcs.size());
Iterator iter = pcs.iterator();
assertEquals("STRING", ((RuntimeTest1) iter.next()).getStringField());
assertEquals("STRING2", ((RuntimeTest2) iter.next()).getStringField());
endEm(pm);
pm = getPM();
idlist = new ArrayList();
idlist.add(_id);
idlist.add(_id);
pcs = pm.findAll(RuntimeTest1.class, idlist);
iter = pcs.iterator();
assertEquals(2, pcs.size());
assertEquals("STRING", ((RuntimeTest1) iter.next()).getStringField());
iter = pcs.iterator();
assertTrue(iter.next() == iter.next());
endEm(pm);
// invalid id causes exception
Object invalidId = new Id(RuntimeTest4.class, -1L);
pm = getPM();
idlist = new ArrayList();
idlist.add(_id);
idlist.add(invalidId);
try {
pcs = (ArrayList) pm.findAll(RuntimeTest1.class, idlist);
iter = pcs.iterator();
assertEquals(2, pcs.size());
assertEquals("STRING",
((RuntimeTest1) iter.next()).getStringField());
assertNotNull(iter.next());
fail("invalid id didnt cause exception");
}
catch (Exception onfe) {
//expected exception. invalid id causes exception
}
try {
((RuntimeTest4) iter.next()).getName();
fail("Accessed invalid object.");
}
catch (Exception onfe) {
bug(1138, onfe, "Wrong exception type");
}
pm = getPM();
try {
pm.findAll(RuntimeTest1.class, idlist);
fail("Found invalid object.");
} catch (Exception e) {
}
endEm(pm);
}
public void testEvictAll() {
OpenJPAEntityManager pm = getPM();
List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
pm.retrieveAll(l);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.PNONTRANS, s);
}
pm.evictAll();
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.HOLLOW, s);
}
}
public void testEvictAllCollection() {
OpenJPAEntityManager pm = getPM();
List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
pm.retrieveAll(l);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.PNONTRANS, s);
}
pm.evictAll(l);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.HOLLOW, s);
}
}
public void testEvictAllClass() {
OpenJPAEntityManager pm = getPM();
List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
pm.retrieveAll(l);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.PNONTRANS, s);
}
pm.evictAll(RuntimeTest1.class);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.HOLLOW, s);
}
}
public void testEvictAllClassFailure() {
OpenJPAEntityManager pm = getPM();
List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
pm.retrieveAll(l);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.PNONTRANS, s);
}
pm.evictAll(RuntimeTest2.class);
boolean foundPNONTRANS = false;
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
if (s == PCState.PNONTRANS) {
foundPNONTRANS = true;
break;
}
}
assertTrue("should have found some RuntimeTest1s that were not "
+ "evicted", foundPNONTRANS);
}
public void testEvictAllExtent() {
OpenJPAEntityManager pm = getPM();
List l = ((Extent) pm.createExtent(RuntimeTest1.class, true)).list();
pm.retrieveAll(l);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.PNONTRANS, s);
}
pm.evictAll(pm.createExtent(RuntimeTest1.class, true));
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.HOLLOW, s);
}
pm.retrieveAll(l);
for (Iterator iter = l.iterator(); iter.hasNext();) {
PCState s = getStateManager(iter.next(), pm).getPCState();
assertEquals(PCState.PNONTRANS, s);
}
pm.evictAll(pm.createExtent(RuntimeTest1.class, false));
for (Iterator iter = l.iterator(); iter.hasNext();) {
Object o = iter.next();
if (o.getClass() == RuntimeTest1.class) {
PCState s = getStateManager(o, pm).getPCState();
assertEquals(PCState.HOLLOW, s);
}
}
}
}