You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2007/11/21 18:41:03 UTC

svn commit: r597155 [2/2] - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ openjpa-kernel/src/main/java/org/apache/openjpa/enhance/ openjpa-kernel/src/main/j...

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractBrokerSerializationTest.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,446 @@
+/*
+ * 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.kernel;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManager;
+
+import org.apache.openjpa.event.AbstractLifecycleListener;
+import org.apache.openjpa.event.AbstractTransactionListener;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.TransactionEvent;
+import org.apache.openjpa.persistence.InvalidStateException;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.jdbc.JDBCFetchPlan;
+import org.apache.openjpa.persistence.jdbc.JoinSyntax;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/*
+ * To test:
+ *  - managed transactions
+ *  - converting non-enhanced classes to enhanced subclasses
+ *    (maybe an ugly ThreadLocal, maybe through PCData?)
+ */
+public abstract class AbstractBrokerSerializationTest<T>
+    extends SingleEMFTestCase {
+
+    private static LifeListener deserializedLifeListener;
+    private static int testGlobalRefreshCount = 0;
+
+    private static TxListener deserializedTxListener;
+    private static int testGlobalBeginCount = 0;
+
+
+    private Object id;
+
+    public void setUp() {
+        testGlobalRefreshCount = 0;
+        deserializedLifeListener = null;
+        testGlobalBeginCount = 0;
+        deserializedTxListener = null;
+
+        setUp(getManagedType(), getSecondaryType(), CLEAR_TABLES,
+            "openjpa.EntityManagerFactoryPool", "true");
+        
+        T e = newManagedInstance();
+        OpenJPAEntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        em.persist(e);
+        em.getTransaction().commit();
+        id = em.getObjectId(e);
+        em.close();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        testGlobalRefreshCount = 0;
+        deserializedLifeListener = null;
+        testGlobalBeginCount = 0;
+        deserializedTxListener = null;
+    }
+
+    public void testEmptyBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+
+        assertTrue(em != em2);
+        assertTrue(
+            JPAFacadeHelper.toBroker(em) != JPAFacadeHelper.toBroker(em2));
+        assertSame(em.getEntityManagerFactory(), em2.getEntityManagerFactory());
+
+        assertSame(em2, JPAFacadeHelper.toBroker(em2)
+            .getUserObject(JPAFacadeHelper.EM_KEY));
+
+        em.close();
+        assertTrue(em2.isOpen());
+        em2.close();
+    }
+
+    public void testNontransactionalBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T e = em.find(getManagedType(), id);
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+
+        assertFalse(em2.getTransaction().isActive());
+
+        assertFalse(em2.contains(e));
+        assertEquals(1*graphSize(), em2.getManagedObjects().size());
+        T e2 = em2.find(getManagedType(), id);
+        assertEquals(em.getObjectId(e), em2.getObjectId(e2));
+
+        em.close();
+        em2.close();
+    }
+
+    public void testUnflushedOptimisticTxBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T e = em.find(getManagedType(), id);
+        OpenJPAEntityManager em2 = null;
+        OpenJPAEntityManager em3 = null;
+        try {
+            em.getTransaction().begin();
+            modifyInstance(e);
+            T newe = newManagedInstance();
+            em.persist(newe);
+            em2 = deserializeEM(serialize(em));
+
+            assertTrue(em2.getTransaction().isActive());
+
+            assertFalse(em2.contains(e));
+            T e2 = em2.find(getManagedType(), id);
+            assertEquals(em.getObjectId(e), em2.getObjectId(e2));
+
+            assertEquals("modified", getModifiedValue(e2));
+
+            em.getTransaction().rollback();
+            assertTrue(em2.getTransaction().isActive());
+            em2.getTransaction().commit();
+
+            em3 = emf.createEntityManager();
+            T e3 = em3.find(getManagedType(), id);
+            assertEquals(getModifiedValue(e2), getModifiedValue(e3));
+            assertTrue(1 < ((Number) em3.createQuery("select count(o) from "
+                + getManagedType().getName() + " o").getSingleResult())
+                .intValue());
+        } finally {
+            close(em);
+            close(em2);
+            close(em3);
+        }
+    }
+
+    public void testFlushedOptimisticTxBrokerSerialization() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T e = em.find(getManagedType(), id);
+        em.getTransaction().begin();
+        modifyInstance(e);
+        em.flush();
+        try {
+            serialize(em);
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("flushed"));
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testConnectedOptimisticTxBrokerSerialization() {
+        Map m = new HashMap();
+        m.put("openjpa.ConnectionRetainMode", "always");
+        OpenJPAEntityManager em = emf.createEntityManager(m);
+        try {
+            serialize(em);
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("connected"));
+        } finally {
+            em.close();
+        }
+    }
+
+    public void testEmptyPessimisticTxBrokerSerialization() {
+        Map m = new HashMap();
+        m.put("openjpa.Optimistic", "false");
+        OpenJPAEntityManager em = emf.createEntityManager(m);
+        em.getTransaction().begin();
+        try {
+            serialize(em);
+            fail("should not be able to serialize");
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("datastore (pessimistic)"));
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testNonEmptyPessimisticTxBrokerSerialization() {
+        Map m = new HashMap();
+        m.put("openjpa.Optimistic", "false");
+        OpenJPAEntityManager em = emf.createEntityManager(m);
+        T e = em.find(getManagedType(), id);
+        em.getTransaction().begin();
+        try {
+            serialize(em);
+            fail("should not be able to serialize");
+        } catch (InvalidStateException ise) {
+            // expected
+            assertTrue(ise.getMessage().contains("datastore (pessimistic)"));
+        } finally {
+            em.getTransaction().rollback();
+            em.close();
+        }
+    }
+
+    public void testFetchConfigurationMutations() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        JDBCFetchPlan plan = (JDBCFetchPlan) em.getFetchPlan();
+
+        assertNotEquals(17, plan.getLockTimeout());
+        assertNotEquals(JoinSyntax.TRADITIONAL, plan.getJoinSyntax());
+
+        plan.setLockTimeout(17);
+        plan.setJoinSyntax(JoinSyntax.TRADITIONAL);
+
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+        JDBCFetchPlan plan2 = (JDBCFetchPlan) em2.getFetchPlan();
+        assertEquals(17, plan2.getLockTimeout());
+        assertEquals(JoinSyntax.TRADITIONAL, plan2.getJoinSyntax());
+    }
+
+    public void testInMemorySavepointsWithNewInstances() {
+        emf.close();
+        OpenJPAEntityManagerFactory emf = createEMF(
+            getManagedType(), getSecondaryType(),
+            "openjpa.EntityManagerFactoryPool", "true",
+            "openjpa.SavepointManager", "in-mem");
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = null;
+        try {
+            em.getTransaction().begin();
+            T t = newManagedInstance();
+            Object orig = getModifiedValue(t);
+            em.persist(t);
+            Object id = em.getObjectId(t);
+            em.setSavepoint("foo");
+            modifyInstance(t);
+            assertNotEquals(orig, getModifiedValue(t));
+
+            em2 = deserializeEM(serialize(em));
+            T t2 = em2.find(getManagedType(), id);
+            assertNotEquals(orig, getModifiedValue(t2));
+
+            em.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t));
+
+            em2.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t2));
+        } finally {
+            close(em);
+            close(em2);
+        }
+    }
+
+    public void testInMemorySavepointsWithModifiedInstances() {
+        emf.close();
+        OpenJPAEntityManagerFactory emf = createEMF(
+            getManagedType(), getSecondaryType(),
+            "openjpa.EntityManagerFactoryPool", "true",
+            "openjpa.SavepointManager", "in-mem");
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = null;
+        try {
+            em.getTransaction().begin();
+            T t = em.find(getManagedType(), id);
+            Object orig = getModifiedValue(t);
+            em.setSavepoint("foo");
+            modifyInstance(t);
+            assertNotEquals(orig, getModifiedValue(t));
+
+            em2 = deserializeEM(serialize(em));
+            T t2 = em2.find(getManagedType(), id);
+            assertNotEquals(orig, getModifiedValue(t2));
+
+            em.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t));
+
+            em2.rollbackToSavepoint("foo");
+            assertEquals(orig, getModifiedValue(t2));
+        } finally {
+            close(em);
+            close(em2);
+        }
+    }
+
+    public void testEventManagers() {
+        TxListener txListener = new TxListener();
+        emf.addTransactionListener(txListener);
+        LifeListener lifeListener = new LifeListener();
+        emf.addLifecycleListener(lifeListener, null);
+
+        OpenJPAEntityManager em = emf.createEntityManager();
+        T t = em.find(getManagedType(), id);
+        assertEquals(0, lifeListener.refreshCount);
+        em.refresh(t);
+        assertEquals(1*graphSize(), lifeListener.refreshCount);
+        em.getTransaction().begin();
+        em.getTransaction().commit();
+        em.getTransaction().begin();
+        em.getTransaction().commit();
+        assertEquals(2, txListener.beginCount);
+
+        OpenJPAEntityManager em2 = deserializeEM(serialize(em));
+        assertNotNull(deserializedLifeListener);
+        assertEquals(1* graphSize(),
+            deserializedLifeListener.refreshCount);
+        assertNotSame(lifeListener, deserializedLifeListener);
+        T t2 = em2.find(getManagedType(), id);
+        em2.refresh(t2);
+        assertEquals(2* graphSize(),
+            deserializedLifeListener.refreshCount);
+
+        // if this is 3*refreshMultiplier(), that means that there are
+        // extra registered listeners
+        assertEquals(2* graphSize(), testGlobalRefreshCount);
+
+
+        assertNotNull(deserializedTxListener);
+        assertEquals(2, deserializedTxListener.beginCount);
+        assertNotSame(txListener, deserializedTxListener);
+        em2.getTransaction().begin();
+        em2.getTransaction().rollback();
+        assertEquals(3, deserializedTxListener.beginCount);
+
+        // if this is 4, that means that there are extra registered listeners
+        assertEquals(3, testGlobalBeginCount);
+    }
+
+    byte[] serialize(Object o) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(o);
+            oos.flush();
+            return baos.toByteArray();
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+    }
+
+    OpenJPAEntityManager deserializeEM(byte[] bytes) {
+        return (OpenJPAEntityManager) deserialize(bytes);
+    }
+
+    private Object deserialize(byte[] bytes) {
+        try {
+            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return ois.readObject();
+        } catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    void close(EntityManager em) {
+        if (em != null && em.isOpen() && em.getTransaction().isActive())
+            em.getTransaction().rollback();
+        if (em != null && em.isOpen())
+            em.close();
+    }
+
+    protected abstract Class<T> getManagedType();
+
+    protected abstract T newManagedInstance();
+
+    protected abstract void modifyInstance(T t);
+
+    protected abstract Object getModifiedValue(T t);
+
+    /**
+     * The number of instances in the graph created
+     * by {@link #newManagedInstance()} of type T.
+     */
+    protected int graphSize() {
+        return 1;
+    }
+
+    /**
+     * An additional type that must be available in this PC. May be null.
+     */
+    protected Class getSecondaryType() {
+        return null;
+    }
+
+    private static class TxListener
+        extends AbstractTransactionListener
+        implements Serializable {
+
+        private int beginCount = 0;
+
+        public TxListener() {
+
+        }
+
+        @Override
+        public void afterBegin(TransactionEvent event) {
+            beginCount++;
+            testGlobalBeginCount++;
+        }
+
+        private void readObject(ObjectInputStream in)
+            throws ClassNotFoundException, IOException {
+            in.defaultReadObject();
+            deserializedTxListener = this;
+        }
+    }
+
+    private static class LifeListener
+        extends AbstractLifecycleListener
+        implements Serializable {
+
+        private int refreshCount = 0;
+
+        @Override
+        public void afterRefresh(LifecycleEvent event) {
+            refreshCount++;
+            testGlobalRefreshCount++;
+        }
+
+        private void readObject(ObjectInputStream in)
+            throws ClassNotFoundException, IOException {
+            in.defaultReadObject();
+            deserializedLifeListener = this;
+        }
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/AbstractUnenhancedRelationBrokerSerializationTest.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,52 @@
+/*
+ * 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.kernel;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.enhance.UnenhancedSubtype;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.util.ImplHelper;
+
+public abstract class AbstractUnenhancedRelationBrokerSerializationTest<T>
+    extends AbstractBrokerSerializationTest<T> {
+
+    public void testNewUnenhancedSMsRegisteredGlobally() {
+        OpenJPAEntityManager em = emf.createEntityManager();
+        OpenJPAEntityManager em2 = null;
+        try {
+            em.getTransaction().begin();
+            UnenhancedSubtype newe = (UnenhancedSubtype) newManagedInstance();
+            em.persist(newe);
+            em2 = deserializeEM(serialize(em));
+
+            for (Object o : em2.getManagedObjects()) {
+                assertFalse(o instanceof PersistenceCapable);
+                assertNotNull(ImplHelper.toPersistenceCapable(o,
+                    emf.getConfiguration()));
+                if (o instanceof UnenhancedSubtype)
+                    assertNotNull(ImplHelper.toPersistenceCapable(
+                        ((UnenhancedSubtype) o).getRelated(),
+                            emf.getConfiguration()));
+            }
+        } finally {
+            close(em);
+            close(em2);
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEnhancedInstanceBrokerSerialization.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,52 @@
+/*
+ * 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.kernel;
+
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.query.SimpleEntity;
+
+public class TestEnhancedInstanceBrokerSerialization
+    extends AbstractBrokerSerializationTest<SimpleEntity> {
+
+    @Override
+    public void setUp() {
+        assertTrue(
+            PersistenceCapable.class.isAssignableFrom(SimpleEntity.class));
+        super.setUp();
+    }
+
+    protected Class<SimpleEntity> getManagedType() {
+        return SimpleEntity.class;
+    }
+
+    protected SimpleEntity newManagedInstance() {
+        SimpleEntity e = new SimpleEntity();
+        e.setName("foo");
+        e.setValue("bar");
+        return e;
+    }
+
+    protected void modifyInstance(SimpleEntity e) {
+        e.setValue("modified");
+    }
+
+    protected Object getModifiedValue(SimpleEntity e) {
+        return e.getValue();
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestEntityManagerFactoryPool.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,53 @@
+/*
+ * 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.kernel;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestEntityManagerFactoryPool
+    extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp("openjpa.EntityManagerFactoryPool", Boolean.TRUE);
+
+        emf.createEntityManager().close();
+    }
+
+    public void testBrokerFactoryPoolHit() {
+        Map m = new HashMap();
+        // also tests string values for the property
+        m.put("openjpa.EntityManagerFactoryPool", "True");
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+            "test", m);
+        assertSame(this.emf, emf);
+    }
+
+    public void testBrokerFactoryPoolMiss() {
+        Map m = new HashMap();
+        m.put("openjpa.EntityManagerFactoryPool", Boolean.TRUE);
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
+            "second-persistence-unit", m);
+        assertNotSame(this.emf, emf);
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestInstanceGraphBrokerSerialization.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,51 @@
+/*
+ * 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.kernel;
+
+import org.apache.openjpa.persistence.query.ManyOneEntity;
+
+public class TestInstanceGraphBrokerSerialization
+    extends AbstractBrokerSerializationTest<ManyOneEntity> {
+
+    protected Class<ManyOneEntity> getManagedType() {
+        return ManyOneEntity.class;
+    }
+
+    protected ManyOneEntity newManagedInstance() {
+        ManyOneEntity e = new ManyOneEntity();
+        e.setName("foo");
+        ManyOneEntity rel = new ManyOneEntity();
+        rel.setName("bar");
+        e.setRel(rel);
+        return e;
+    }
+
+    protected void modifyInstance(ManyOneEntity e) {
+        e.getRel().setName("modified");
+    }
+
+    protected Object getModifiedValue(ManyOneEntity e) {
+        return e.getRel().getName();
+    }
+
+    @Override
+    protected int graphSize() {
+        return 2;
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessInstanceBrokerSerialization.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,43 @@
+/*
+ * 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.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedFieldAccess;
+
+public class TestUnenhancedFieldAccessInstanceBrokerSerialization
+    extends AbstractBrokerSerializationTest<UnenhancedFieldAccess> {
+
+    protected Class<UnenhancedFieldAccess> getManagedType() {
+        return UnenhancedFieldAccess.class;
+    }
+
+    protected UnenhancedFieldAccess newManagedInstance() {
+        UnenhancedFieldAccess e = new UnenhancedFieldAccess();
+        e.setStringField("foo");
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedFieldAccess e) {
+        e.setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedFieldAccess e) {
+        return e.getStringField();
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,57 @@
+/*
+ * 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.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedFieldAccess;
+import org.apache.openjpa.enhance.UnenhancedFieldAccessSubclass;
+
+public class TestUnenhancedFieldAccessWithRelationInstanceBrokerSerialization
+    extends AbstractUnenhancedRelationBrokerSerializationTest
+        <UnenhancedFieldAccessSubclass> {
+
+    protected Class getSecondaryType() {
+        return UnenhancedFieldAccess.class;
+    }
+
+    protected Class<UnenhancedFieldAccessSubclass> getManagedType() {
+        return UnenhancedFieldAccessSubclass.class;
+    }
+
+    protected UnenhancedFieldAccessSubclass newManagedInstance() {
+        UnenhancedFieldAccessSubclass e = new UnenhancedFieldAccessSubclass();
+        e.setStringField("foo");
+        UnenhancedFieldAccess related = new UnenhancedFieldAccess();
+        related.setStringField("bar");
+        e.setRelated(related);
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedFieldAccessSubclass e) {
+        e.getRelated().setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedFieldAccessSubclass e) {
+        return e.getRelated().getStringField();
+    }
+
+    @Override
+    protected int graphSize() {
+        return 2;
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessInstanceBrokerSerialization.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,43 @@
+/*
+ * 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.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
+
+public class TestUnenhancedPropertyAccessInstanceBrokerSerialization
+    extends AbstractBrokerSerializationTest<UnenhancedPropertyAccess> {
+
+    protected Class<UnenhancedPropertyAccess> getManagedType() {
+        return UnenhancedPropertyAccess.class;
+    }
+
+    protected UnenhancedPropertyAccess newManagedInstance() {
+        UnenhancedPropertyAccess e = new UnenhancedPropertyAccess();
+        e.setStringField("foo");
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedPropertyAccess e) {
+        e.setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedPropertyAccess e) {
+        return e.getStringField();
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java?rev=597155&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/kernel/TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization.java Wed Nov 21 09:40:54 2007
@@ -0,0 +1,58 @@
+/*
+ * 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.kernel;
+
+import org.apache.openjpa.enhance.UnenhancedPropertyAccess;
+import org.apache.openjpa.enhance.UnenhancedPropertyAccessSubclass;
+
+public class TestUnenhancedPropertyAccessWithRelationInstanceBrokerSerialization
+    extends AbstractUnenhancedRelationBrokerSerializationTest
+        <UnenhancedPropertyAccessSubclass> {
+
+    protected Class getSecondaryType() {
+        return UnenhancedPropertyAccess.class;
+    }
+
+    protected Class<UnenhancedPropertyAccessSubclass> getManagedType() {
+        return UnenhancedPropertyAccessSubclass.class;
+    }
+
+    protected UnenhancedPropertyAccessSubclass newManagedInstance() {
+        UnenhancedPropertyAccessSubclass e =
+            new UnenhancedPropertyAccessSubclass();
+        e.setStringField("foo");
+        UnenhancedPropertyAccess related = new UnenhancedPropertyAccess();
+        related.setStringField("bar");
+        e.setRelated(related);
+        return e;
+    }
+
+    protected void modifyInstance(UnenhancedPropertyAccessSubclass e) {
+        e.getRelated().setStringField("modified");
+    }
+
+    protected Object getModifiedValue(UnenhancedPropertyAccessSubclass e) {
+        return e.getRelated().getStringField();
+    }
+
+    @Override
+    protected int graphSize() {
+        return 2;
+    }
+}
\ No newline at end of file

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java?rev=597155&r1=597154&r2=597155&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/ManyOneEntity.java Wed Nov 21 09:40:54 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.openjpa.persistence.query;
 
+import java.io.Serializable;
 import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
@@ -29,7 +30,7 @@
 
 @Entity
 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
-public class ManyOneEntity {
+public class ManyOneEntity implements Serializable {
 
     @Id
     @GeneratedValue

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java?rev=597155&r1=597154&r2=597155&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/SimpleEntity.java Wed Nov 21 09:40:54 2007
@@ -18,6 +18,7 @@
  */
 package org.apache.openjpa.persistence.query;
 
+import java.io.Serializable;
 import javax.persistence.Basic;
 import javax.persistence.Column;
 import javax.persistence.Entity;
@@ -43,7 +44,7 @@
         @FieldResult(name = "value", column = "VALUE") }))
 @Entity(name = "simple")
 @Table(name = "SIMPLE_ENTITY")
-public class SimpleEntity {
+public class SimpleEntity implements Serializable {
 
     @Id
     @GeneratedValue

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?rev=597155&r1=597154&r2=597155&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java Wed Nov 21 09:40:54 2007
@@ -18,6 +18,15 @@
  */
 package org.apache.openjpa.persistence;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
 import java.lang.reflect.Array;
 import java.util.Arrays;
 import java.util.Collection;
@@ -30,6 +39,9 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.enhance.PCEnhancer;
+import org.apache.openjpa.enhance.PCRegistry;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
 import org.apache.openjpa.kernel.Broker;
 import org.apache.openjpa.kernel.DelegatingBroker;
 import org.apache.openjpa.kernel.FindCallbacks;
@@ -40,8 +52,8 @@
 import org.apache.openjpa.kernel.QueryLanguages;
 import org.apache.openjpa.kernel.Seq;
 import org.apache.openjpa.kernel.jpql.JPQLParser;
-import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.lib.util.Closeable;
+import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.FieldMetaData;
 import org.apache.openjpa.meta.QueryMetaData;
@@ -59,30 +71,36 @@
  * @nojavadoc
  */
 public class EntityManagerImpl
-    implements OpenJPAEntityManagerSPI,
+    implements OpenJPAEntityManagerSPI, Externalizable,
     FindCallbacks, OpCallbacks, Closeable, OpenJPAEntityTransaction {
 
     private static final Localizer _loc = Localizer.forPackage
         (EntityManagerImpl.class);
+    private static final Object[] EMPTY_OBJECTS = new Object[0];
 
-    private final DelegatingBroker _broker;
-    private final EntityManagerFactoryImpl _emf;
+    private DelegatingBroker _broker;
+    private EntityManagerFactoryImpl _emf;
     private FetchPlan _fetch = null;
-    private static final Object[] EMPTY_OBJECTS = new Object[0];
 
     private RuntimeExceptionTranslator ret =
         PersistenceExceptions.getRollbackTranslator(this);
 
+    public EntityManagerImpl() {
+        // for Externalizable
+    }
+
     /**
      * Constructor; supply factory and delegate.
      */
     public EntityManagerImpl(EntityManagerFactoryImpl factory,
         Broker broker) {
+        initialize(factory, broker);
+    }
+
+    private void initialize(EntityManagerFactoryImpl factory, Broker broker) {
         _emf = factory;
-        RuntimeExceptionTranslator translator =
-            PersistenceExceptions.getRollbackTranslator(this);
-        _broker = new DelegatingBroker(broker, translator);
-        _broker.setImplicitBehavior(this, translator);
+        _broker = new DelegatingBroker(broker, ret);
+        _broker.setImplicitBehavior(this, ret);
     }
 
     /**
@@ -1179,5 +1197,145 @@
         if (!(other instanceof EntityManagerImpl))
             return false;
         return _broker.equals(((EntityManagerImpl) other)._broker);
+    }
+
+    public void readExternal(ObjectInput in)
+        throws IOException, ClassNotFoundException {
+        try {
+            ret = PersistenceExceptions.getRollbackTranslator(this);
+
+            // this assumes that serialized Brokers are from something
+            // that extends AbstractBrokerFactory.
+            Object factoryKey = in.readObject();
+            AbstractBrokerFactory factory =
+                AbstractBrokerFactory.getPooledFactoryForKey(factoryKey);
+            byte[] brokerBytes = (byte[]) in.readObject();
+            ObjectInputStream innerIn = new BrokerBytesInputStream(brokerBytes,
+                factory.getConfiguration());
+
+            Broker broker = (Broker) innerIn.readObject();
+            EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl)
+                JPAFacadeHelper.toEntityManagerFactory(
+                    broker.getBrokerFactory());
+            broker.putUserObject(JPAFacadeHelper.EM_KEY, this);
+            initialize(emf, broker);
+        } catch (RuntimeException re) {
+            try {
+                re = ret.translate(re);
+            } catch (Exception e) {
+                // ignore
+            }
+            throw re;
+        }
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        try {
+            // this requires that only AbstractBrokerFactory-sourced
+            // brokers can be serialized
+            Object factoryKey = ((AbstractBrokerFactory) _broker
+                .getBrokerFactory()).getPoolKey();
+            out.writeObject(factoryKey);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream innerOut = new ObjectOutputStream(baos);
+            innerOut.writeObject(_broker.getDelegate());
+            innerOut.flush();
+            out.writeObject(baos.toByteArray());
+        } catch (RuntimeException re) {
+            try {
+                re = ret.translate(re);
+            } catch (Exception e) {
+                // ignore
+            }
+            throw re;
+        }
+    }
+
+    private static class BrokerBytesInputStream extends ObjectInputStream {
+
+        private OpenJPAConfiguration conf;
+
+        BrokerBytesInputStream(byte[] bytes, OpenJPAConfiguration conf)
+            throws IOException {
+            super(new ByteArrayInputStream(bytes));
+            if (conf == null)
+                throw new IllegalArgumentException(
+                    "Illegal null argument to ObjectInputStreamWithLoader");
+            this.conf = conf;
+        }
+
+        /**
+         * Make a primitive array class
+         */
+        private Class primitiveType(char type) {
+            switch (type) {
+                case 'B': return byte.class;
+                case 'C': return char.class;
+                case 'D': return double.class;
+                case 'F': return float.class;
+                case 'I': return int.class;
+                case 'J': return long.class;
+                case 'S': return short.class;
+                case 'Z': return boolean.class;
+                default: return null;
+            }
+        }
+
+        protected Class resolveClass(ObjectStreamClass classDesc)
+            throws IOException, ClassNotFoundException {
+
+            String cname = classDesc.getName();
+            if (cname.startsWith("[")) {
+                // An array
+                Class component;		// component class
+                int dcount;			    // dimension
+                for (dcount=1; cname.charAt(dcount)=='['; dcount++) ;
+                if (cname.charAt(dcount) == 'L') {
+                    component = lookupClass(cname.substring(dcount+1,
+                        cname.length()-1));
+                } else {
+                    if (cname.length() != dcount+1) {
+                        throw new ClassNotFoundException(cname);// malformed
+                    }
+                    component = primitiveType(cname.charAt(dcount));
+                }
+                int dim[] = new int[dcount];
+                for (int i=0; i<dcount; i++) {
+                    dim[i]=0;
+                }
+                return Array.newInstance(component, dim).getClass();
+            } else {
+                return lookupClass(cname);
+            }
+        }
+
+        /**
+         * If this is a generated subclass, look up the corresponding Class
+         * object via metadata.
+         */
+        private Class lookupClass(String className)
+            throws ClassNotFoundException {
+            try {
+                return Class.forName(className);
+            } catch (ClassNotFoundException e) {
+                if (PCEnhancer.isPCSubclassName(className)) {
+                    String superName = PCEnhancer.toManagedTypeName(className);
+                    ClassMetaData[] metas = conf.getMetaDataRepositoryInstance()
+                        .getMetaDatas();
+                    for (int i = 0; i < metas.length; i++) {
+                        if (superName.equals(
+                            metas[i].getDescribedType().getName())) {
+                            return PCRegistry.getPCType(
+                                metas[i].getDescribedType());
+                        }
+                    }
+
+                    // if it's not found, try to look for it anyways
+                    return Class.forName(className);
+                } else {
+                    throw e;
+                }
+            }
+        }
     }
 }

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java?rev=597155&r1=597154&r2=597155&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java Wed Nov 21 09:40:54 2007
@@ -51,8 +51,8 @@
      * and {@link NonUniqueResultException} in accordance with
      * section 3.7 of the EJB 3.0 specification.
      */
-    public static RuntimeExceptionTranslator getRollbackTranslator
-        (final OpenJPAEntityManager em) {
+    public static RuntimeExceptionTranslator getRollbackTranslator(
+        final OpenJPAEntityManager em) {
         return new RuntimeExceptionTranslator() {
             private boolean throwing = false;
 

Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java?rev=597155&r1=597154&r2=597155&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java (original)
+++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java Wed Nov 21 09:40:54 2007
@@ -22,6 +22,8 @@
 import java.lang.instrument.IllegalClassFormatException;
 import java.security.ProtectionDomain;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 import javax.persistence.EntityManager;
 import javax.persistence.spi.ClassTransformer;
 import javax.persistence.spi.PersistenceProvider;
@@ -54,6 +56,7 @@
     implements PersistenceProvider {
 
     static final String CLASS_TRANSFORMER_OPTIONS = "ClassTransformerOptions";
+    private static final String EMF_POOL = "EntityManagerFactoryPool";
 
     private static final Localizer _loc = Localizer.forPackage(
         PersistenceProviderImpl.class);
@@ -72,17 +75,37 @@
         String resource, Map m) {
         PersistenceProductDerivation pd = new PersistenceProductDerivation();
         try {
+            Object poolValue = Configurations.removeProperty(EMF_POOL, m);
             ConfigurationProvider cp = pd.load(resource, name, m);
             if (cp == null)
                 return null;
 
-            BrokerFactory factory = Bootstrap.newBrokerFactory(cp, null);
+            BrokerFactory factory = getBrokerFactory(cp, poolValue, null);
             return JPAFacadeHelper.toEntityManagerFactory(factory);
         } catch (Exception e) {
             throw PersistenceExceptions.toPersistenceException(e);
         }
     }
 
+    private BrokerFactory getBrokerFactory(ConfigurationProvider cp,
+        Object poolValue, ClassLoader loader) {
+        // handle "true" and "false"
+        if (poolValue instanceof String
+            && ("true".equalsIgnoreCase((String) poolValue)
+                || "false".equalsIgnoreCase((String) poolValue)))
+            poolValue = Boolean.valueOf((String) poolValue);
+
+        if (poolValue != null && !(poolValue instanceof Boolean)) {
+            // we only support boolean settings for this option currently.
+            throw new IllegalArgumentException(poolValue.toString());
+        }
+        
+        if (poolValue == null || !((Boolean) poolValue).booleanValue())
+            return Bootstrap.newBrokerFactory(cp, loader);
+        else
+            return Bootstrap.getBrokerFactory(cp, loader);
+    }
+
     public OpenJPAEntityManagerFactory createEntityManagerFactory(String name,
         Map m) {
         return createEntityManagerFactory(name, null, m);
@@ -92,6 +115,7 @@
         PersistenceUnitInfo pui, Map m) {
         PersistenceProductDerivation pd = new PersistenceProductDerivation();
         try {
+            Object poolValue = Configurations.removeProperty(EMF_POOL, m);
             ConfigurationProvider cp = pd.load(pui, m);
             if (cp == null)
                 return null;
@@ -117,7 +141,7 @@
                     BrokerValue.NON_FINALIZING_ALIAS);
             }
 
-            BrokerFactory factory = Bootstrap.newBrokerFactory(cp, 
+            BrokerFactory factory = getBrokerFactory(cp, poolValue,
                 pui.getClassLoader());
             if (transformerException != null) {
                 Log log = factory.getConfiguration().getLog(