openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From p..@apache.org
Subject svn commit: r627979 [11/39] - in /openjpa/trunk: openjpa-lib/src/test/java/org/apache/openjpa/lib/test/ openjpa-persistence-jdbc/ openjpa-persistence-jdbc/src/test/java/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/ openjpa-per...
Date Fri, 15 Feb 2008 09:20:40 GMT
Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/TestCascades.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,1142 @@
+/*
+ * 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.entityoperation;
+
+
+import org.apache.openjpa.persistence.entityoperation.common.apps.CascadesEntity;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+/**
+ * <p>Test EJB persistence cascade options.</p>
+ *
+ * @author Abe White
+ */
+public class TestCascades extends AbstractTestCase {
+
+    public TestCascades(String name) {
+        super(name, "entityopcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(CascadesEntity.class);
+    }
+
+    public void testNoCascadePersist ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (ent));
+         assertFalse (em.isPersistent (rel));
+         rollbackTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadePersistIsImmediate ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         ent.setAll (rel1);
+         ent.getAllCollection ().add (rel2);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (ent));
+         assertTrue (em.isPersistent (rel1));
+         assertTrue (em.isPersistent (rel2));
+         rollbackTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadePersistFlushWithDeletedCausesException ()
+     {
+         CascadesEntity rel = new CascadesEntity ();
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (rel);
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         CascadesEntity ent = new CascadesEntity ();
+         ent.setNone (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with deleted object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception e)
+         {}
+
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         ent = new CascadesEntity ();
+         ent.getNoneCollection ().add (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with deleted object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception re)
+         {
+         }
+         assertTrue (!em.getTransaction().isActive ());
+
+         endEm(em);
+     }
+
+
+     public void testCascadePersistFlushWithDeleted ()
+     {
+         CascadesEntity rel = new CascadesEntity ();
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (rel);
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         CascadesEntity ent = new CascadesEntity ();
+         ent.setAll (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         endTx(em);
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         ent = new CascadesEntity ();
+         ent.getAllCollection ().add (rel);
+         startTx(em);
+         em.remove (rel);
+         em.persist (ent);
+         endTx(em);
+         assertTrue (!em.getTransaction().isActive ());
+
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         rel = em.find (CascadesEntity.class, id);
+         assertNotNull (rel);
+         endEm(em);
+     }
+
+
+     public void testNoCascadePersistFlushWithTransientCausesException ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with transient object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception re)
+         {
+         }
+
+
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         ent.getNoneCollection ().add (rel);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         try
+         {
+             endTx(em);
+             fail ("Allowed flush with transient object in non-cascade-persist "
+                 + "relation field");
+         }
+         catch (RuntimeException re)
+         {
+         }
+         catch (Exception re)
+         {
+         }
+         assertTrue (!em.getTransaction().isActive ());
+         endEm(em);
+     }
+
+
+     public void testNoCascadePersistFlushWithPersistent ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertFalse(em.isPersistent (rel));
+         em.persist (rel);
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         ent.getNoneCollection ().add (rel);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         startTx(em);
+         em.persist (ent);
+         assertFalse (em.isPersistent (rel));
+         em.persist (rel);
+         endTx(em);
+         id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         endEm(em);
+     }
+
+
+     public void testCascadePersistFlushWithTransient ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         ent.setAll (rel);
+         assertFalse (em.isPersistent (rel));
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         startTx(em);
+         em.persist (ent);
+         ent.getAllCollection ().add (rel);
+         assertFalse (em.isPersistent (rel));
+         endTx(em);
+         id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         endEm(em);
+     }
+
+
+     public void testCascadePersistFlushWithPersistent ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setAll (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (rel));
+         endTx(em);
+         long id = rel.getId ();
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         ent.getAllCollection ().add (rel);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         startTx(em);
+         em.persist (ent);
+         assertTrue (em.isPersistent (rel));
+         endTx(em);
+         id = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNotNull (em.find (CascadesEntity.class, id));
+         endEm(em);
+     }
+
+
+     public void testCascadeCircleThroughPersistent ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         CascadesEntity top = new CascadesEntity ();
+         top.setAll (ent);
+         CascadesEntity rel = new CascadesEntity ();
+
+         startTx(em);
+         ent.setAll (rel);
+         rel.setAll (top);
+         em.persist (top);
+         assertTrue (em.isPersistent (top));
+         assertTrue (em.isPersistent (ent));
+         assertTrue (em.isPersistent (rel));
+         rollbackTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeDelete ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         CascadesEntity depend = new CascadesEntity ();
+         ent.setNone (rel);
+         ent.setDependent (depend);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel, depend);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         long dependId = depend.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getNone ();
+         depend = ent.getDependent ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (dependId, depend.getId ());
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (relId, ent.getNoneCollection ().iterator ().next ().getId ());
+
+         startTx(em);
+         em.remove (ent);
+         assertTrue (em.isRemoved (ent));
+         assertFalse (em.isRemoved (rel));
+         assertFalse (em.isRemoved (depend));
+         endTx(em);
+         assertFalse (em.isPersistent (ent));
+         assertTrue (em.isPersistent (rel));
+         assertFalse (em.isPersistent (depend));
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id));
+         assertNotNull (em.find (CascadesEntity.class, relId));
+         assertNull (em.find (CascadesEntity.class, dependId));
+         endEm(em);
+     }
+
+
+     public void testDeepCascadeDelete ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         CascadesEntity depend = new CascadesEntity ();
+         CascadesEntity deep1 = new CascadesEntity ();
+         CascadesEntity deep2 = new CascadesEntity ();
+         CascadesEntity deep3 = new CascadesEntity ();
+         ent.setAll (rel1);
+         rel1.setAll (deep1);
+         ent.getAllCollection ().add (rel2);
+         rel2.getAllCollection ().add (deep2);
+         ent.setDependent (depend);
+         depend.setAll (deep3);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, depend);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         long deep1Id = deep1.getId ();
+         long deep2Id = deep2.getId ();
+         long deep3Id = deep3.getId ();
+         long dependId = depend.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel1 = ent.getAll ();
+         assertEquals (rel1Id, rel1.getId ());
+         deep1 = rel1.getAll ();
+         assertEquals (deep1Id, deep1.getId ());
+         assertEquals (1, ent.getAllCollection ().size ());
+         rel2 = ent.getAllCollection ().iterator ().next ();
+         assertEquals (rel2Id, rel2.getId ());
+         assertEquals (1, rel2.getAllCollection ().size ());
+         deep2 = rel2.getAllCollection ().iterator ().next ();
+         assertEquals (deep2Id, deep2.getId ());
+         depend = ent.getDependent ();
+         assertEquals (dependId, depend.getId ());
+         deep3 = depend.getAll ();
+         assertEquals (deep3Id, deep3.getId ());
+
+         startTx(em);
+         em.remove (ent);
+         assertTrue (em.isRemoved (ent));
+         assertTrue (em.isRemoved (rel1));
+         assertTrue (em.isRemoved (rel2));
+         assertTrue (em.isRemoved (deep1));
+         assertTrue (em.isRemoved (deep2));
+         assertFalse (em.isRemoved (depend));
+         assertFalse (em.isRemoved (deep3));
+         endTx(em);
+         assertFalse (em.isPersistent (ent));
+         assertFalse (em.isPersistent (rel1));
+         assertFalse (em.isPersistent (rel2));
+         assertFalse (em.isPersistent (deep1));
+         assertFalse (em.isPersistent (depend));
+         assertFalse (em.isPersistent (deep2));
+         assertFalse(em.isPersistent (deep3));
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id));
+         assertNull (em.find (CascadesEntity.class, rel1Id));
+         assertNull (em.find (CascadesEntity.class, rel2Id));
+         assertNull (em.find (CascadesEntity.class, deep1Id));
+         assertNull (em.find (CascadesEntity.class, deep2Id));
+         assertNull (em.find (CascadesEntity.class, deep3Id));
+         assertNull (em.find (CascadesEntity.class, dependId));
+         endEm(em);
+     }
+
+
+     public void testCircularCascadeDelete ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setAll (rel);
+         ent.getAllCollection ().add (rel);
+         rel.setAll (ent);
+         rel.getAllCollection ().add (ent);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getAll ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (rel, ent.getAllCollection ().iterator ().next ());
+         assertEquals (ent, rel.getAllCollection ().iterator ().next ());
+
+         startTx(em);
+         em.remove (ent);
+         assertTrue (em.isRemoved (ent));
+         assertTrue (em.isRemoved (rel));
+         endTx(em);
+         assertFalse (em.isPersistent (ent));
+         assertFalse (em.isPersistent (rel));
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id));
+         assertNull (em.find (CascadesEntity.class, relId));
+         endEm(em);
+     }
+
+
+     public void testNoCascadeRefresh ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getNone ();
+         assertEquals (relId, rel.getId ());
+
+         startTx(em);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         ent.setDependent (new CascadesEntity ());
+         rel.setDependent (new CascadesEntity ());
+         em.persist (ent.getDependent ());
+         em.persist (rel.getDependent ());
+         em.refresh (ent);
+         assertNull (ent.getDependent ());
+         assertNotNull (rel.getDependent ());
+         endTx(em);
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         assertNull (em.find (CascadesEntity.class, id).getDependent ());
+         assertNotNull (em.find (CascadesEntity.class, relId).getDependent ());
+         endEm(em);
+     }
+
+
+     public void testCircularCascadeRefresh ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setAll (rel);
+         rel.setAll (ent);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getAll ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (ent, rel.getAll ());
+
+         startTx(em);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         ent.setDependent (new CascadesEntity ());
+         rel.setDependent (new CascadesEntity ());
+         em.persist (ent.getDependent ());
+         em.persist (rel.getDependent ());
+         em.refresh (ent);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         endTx(em);
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         assertEquals (relId, ent.getAll ().getId ());
+         assertNull (ent.getDependent ());
+         assertNull (em.find (CascadesEntity.class, relId).getDependent ());
+         endEm(em);
+
+         ent = new CascadesEntity ();
+         rel = new CascadesEntity ();
+         CascadesEntity deep = new CascadesEntity ();
+         ent.getAllCollection ().add (rel);
+         rel.getAllCollection ().add (ent);
+         rel.getAllCollection ().add (deep);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         id = ent.getId ();
+         relId = rel.getId ();
+         long deepId = deep.getId ();
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         rel = ent.getAllCollection ().iterator ().next ();
+         assertEquals (relId, rel.getId ());
+         assertEquals (2, rel.getAllCollection ().size ());
+         deep = null;
+         for (CascadesEntity elem : rel.getAllCollection ())
+             if (elem != ent)
+                 deep = elem;
+         assertEquals (deepId, deep.getId ());
+
+         startTx(em);
+         assertNull (ent.getDependent ());
+         assertNull (rel.getDependent ());
+         assertNull (deep.getDependent ());
+         ent.setDependent (new CascadesEntity ());
+         ent.getAllCollection ().add (new CascadesEntity ());
+         rel.setDependent (new CascadesEntity ());
+         deep.setDependent (new CascadesEntity ());
+         em.persistAll (ent.getAllCollection ());
+         em.persist (ent.getDependent ());
+         em.persist (rel.getDependent ());
+         em.persist (deep.getDependent ());
+         em.refresh (ent);
+         assertNull (ent.getDependent ());
+         assertEquals (1, ent.getAllCollection ().size ());
+         assertTrue (ent.getAllCollection ().contains (rel));
+         assertNull (rel.getDependent ());
+         assertEquals (2, rel.getAllCollection ().size ());
+         assertTrue (rel.getAllCollection ().contains (ent));
+         assertTrue (rel.getAllCollection ().contains (deep));
+         assertNull (deep.getDependent ());
+         endTx(em);
+         endEm(em);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         ent = em.find (CascadesEntity.class, id);
+         assertEquals (1, ent.getAllCollection ().size ());
+         assertEquals (relId, ent.getAllCollection ().iterator ().next ().
+             getId ());
+         assertNull (ent.getDependent ());
+         assertNull (em.find (CascadesEntity.class, relId).getDependent ());
+         assertNull (em.find (CascadesEntity.class, deepId).getDependent ());
+         endEm(em);
+     }
+
+
+     public void testNoCascadeAttachClean ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel", rel.getName ());
+         assertEquals (rel, ent.getNone ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (!em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (ent.getNone () != rel);
+         rel = ent.getNone ();
+         assertNotNull (rel);
+         assertTrue (!em.isDirty (rel));
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+
+         assertTrue (em.isPersistent (rel));
+         assertEquals (relId, rel.getId ());
+         assertEquals ("rel", rel.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadeAttachClean ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         ent.setName ("ent");
+         rel1.setName ("rel1");
+         ent.setAll (rel1);
+         rel2.setName ("rel2");
+         ent.getAllCollection ().add (rel2);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel1", rel1.getName ());
+         assertEquals ("rel2", rel2.getName ());
+         assertEquals (rel1, ent.getAll ());
+         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (!em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (rel1 != ent.getAll ());
+         rel1 = ent.getAll ();
+         assertTrue (!em.isDirty (rel1));
+         assertEquals (1, ent.getAllCollection ().size ());
+         rel2 = ent.getAllCollection ().iterator ().next ();
+         assertTrue (!em.isDirty (rel2));
+
+         assertTrue (em.isPersistent (rel1));
+         assertEquals (rel1Id, rel1.getId ());
+         assertEquals ("rel1", rel1.getName ());
+         assertTrue (em.isPersistent (rel2));
+         assertEquals (rel2Id, rel2.getId ());
+         assertEquals ("rel2", rel2.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeAttachDirtyFields ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel", rel.getName ());
+         assertEquals (rel, ent.getNone ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+         rel.setName ("foo");
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (!em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (ent.getNone () != rel);
+         rel = ent.getNone ();
+         assertNotNull (rel);
+         assertTrue (!em.isDirty (rel));
+         assertEquals (relId, rel.getId ());
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+
+         assertTrue (em.isPersistent (rel));
+         assertEquals (relId, rel.getId ());
+         assertEquals ("rel", rel.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadeAttachDirtyFields ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         ent.setName ("ent");
+         rel1.setName ("rel1");
+         ent.setAll (rel1);
+         rel2.setName ("rel2");
+         ent.getAllCollection ().add (rel2);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persist (ent);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel1", rel1.getName ());
+         assertEquals ("rel2", rel2.getName ());
+         assertEquals (rel1, ent.getAll ());
+         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
+         rel1.setName ("foo");
+         rel2.setName ("bar");
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertEquals ("ent", ent.getName ());
+         assertTrue (!em.isDirty (ent));
+         assertEquals (id, ent.getId ());
+         assertTrue (rel1 != ent.getAll ());
+         rel1 = ent.getAll ();
+         assertTrue (em.isDirty (rel1));
+         assertEquals (1, ent.getAllCollection ().size ());
+         rel2 = ent.getAllCollection ().iterator ().next ();
+         assertTrue (em.isDirty (rel2));
+
+         assertTrue (em.isPersistent (rel1));
+         assertEquals (rel1Id, rel1.getId ());
+         assertEquals ("foo", rel1.getName ());
+         assertTrue (em.isPersistent (rel2));
+         assertEquals (rel2Id, rel2.getId ());
+         assertEquals ("bar", rel2.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeAttachDirtyRelations ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         CascadesEntity other = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         other.setName ("other");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel, other);
+         endTx(em);
+         long id = ent.getId ();
+         long relId = rel.getId ();
+         long otherId = other.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel", rel.getName ());
+         assertEquals ("other", other.getName ());
+         assertEquals (rel, ent.getNone ());
+         assertEquals (rel, ent.getNoneCollection ().iterator ().next ());
+         other.setName ("foo");
+         ent.setNone (other);
+         ent.getNoneCollection ().remove (rel);
+         ent.getNoneCollection ().add (other);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertTrue (em.isDirty (ent));
+         assertEquals ("ent", ent.getName ());
+         assertEquals (id, ent.getId ());
+         assertTrue (ent.getNone () != rel);
+         assertTrue (ent.getNone () != other);
+         other = ent.getNone ();
+         assertNotNull (other);
+         assertTrue (!em.isDirty (other));
+         assertEquals (otherId, other.getId ());
+         assertEquals (1, ent.getNoneCollection ().size ());
+         assertEquals (other, ent.getNoneCollection ().iterator ().next ());
+
+         assertTrue (em.isPersistent (other));
+         assertFalse (em.isPersistent (rel));
+         assertEquals (otherId, other.getId ());
+         assertEquals ("other", other.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testCascadeAttachDirtyRelations ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel1 = new CascadesEntity ();
+         CascadesEntity rel2 = new CascadesEntity ();
+         CascadesEntity other1 = new CascadesEntity ();
+         CascadesEntity other2 = new CascadesEntity ();
+         ent.setName ("ent");
+         rel1.setName ("rel1");
+         ent.setAll (rel1);
+         rel2.setName ("rel2");
+         ent.getAllCollection ().add (rel2);
+         other1.setName ("other1");
+         other2.setName ("other2");
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, other1, other2);
+         endTx(em);
+         long id = ent.getId ();
+         long rel1Id = rel1.getId ();
+         long rel2Id = rel2.getId ();
+         long other1Id = other1.getId ();
+         long other2Id = other2.getId ();
+         endEm(em);
+
+         assertEquals ("ent", ent.getName ());
+         assertEquals ("rel1", rel1.getName ());
+         assertEquals ("rel2", rel2.getName ());
+         assertEquals (rel1, ent.getAll ());
+         assertEquals (rel2, ent.getAllCollection ().iterator ().next ());
+         assertEquals ("other1", other1.getName ());
+         other1.setName ("foo");
+         assertEquals ("other2", other2.getName ());
+         other2.setName ("bar");
+         ent.setAll (other1);
+         ent.getAllCollection ().remove (rel2);
+         ent.getAllCollection ().add (other2);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         ent = em.merge (ent);
+         assertEquals ("ent", ent.getName ());
+         assertTrue (em.isDirty (ent));
+         assertEquals (id, ent.getId ());
+         assertTrue (rel1 != ent.getAll ());
+         assertTrue (other1 != ent.getAll ());
+         other1 = ent.getAll ();
+         assertTrue (em.isDirty (other1));
+         assertEquals (1, ent.getAllCollection ().size ());
+         other2 = ent.getAllCollection ().iterator ().next ();
+         assertTrue (em.isDirty (other2));
+
+         assertTrue (em.isPersistent (other1));
+         assertEquals (other1Id, other1.getId ());
+         assertEquals ("foo", other1.getName ());
+         assertTrue (em.isPersistent (other2));
+         assertEquals (other2Id, other2.getId ());
+         assertEquals ("bar", other2.getName ());
+         endTx(em);
+         endEm(em);
+     }
+
+
+     public void testNoCascadeReferenceIsPreLoadedReference ()
+     {
+         CascadesEntity ent = new CascadesEntity ();
+         CascadesEntity rel = new CascadesEntity ();
+         CascadesEntity other = new CascadesEntity ();
+         ent.setName ("ent");
+         rel.setName ("rel");
+         other.setName ("other");
+         ent.setNone (rel);
+         ent.getNoneCollection ().add (rel);
+
+         OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         em.persistAll (ent, rel, other);
+         endTx(em);
+         long otherId = other.getId ();
+         endEm(em);
+
+         ent.setNone (other);
+         ent.getNoneCollection ().remove (rel);
+         ent.getNoneCollection ().add (other);
+
+         em = (OpenJPAEntityManager)currentEntityManager();
+         startTx(em);
+         other = em.find (CascadesEntity.class, otherId);
+         ent = em.merge (ent);
+         assertEquals (other, ent.getNone ());
+         assertEquals (other, ent.getNoneCollection ().iterator ().next ());
+         endTx(em);
+         endEm(em);
+     }
+
+    public void testNoCascadeNewCausesException() {
+        CascadesEntity ent = new CascadesEntity();
+        CascadesEntity rel = new CascadesEntity();
+        ent.setNone(rel);
+
+        OpenJPAEntityManager em =
+            (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persistAll(ent, rel);
+        endTx(em);
+        endEm(em);
+
+        CascadesEntity other = new CascadesEntity();
+        ent.setNone(other);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        try {
+            ent = em.merge(ent);
+            fail("Allowed merge of new instance in non-cascading relation.");
+        }
+        catch (RuntimeException re) {
+            if (isActiveTx(em))
+                rollbackTx(em);
+        }
+        endEm(em);
+
+        ent = new CascadesEntity();
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        em.persist(ent);
+        endTx(em);
+        endEm(em);
+
+        other = new CascadesEntity();
+        ent.getNoneCollection().add(other);
+
+        em = (OpenJPAEntityManager) currentEntityManager();
+        startTx(em);
+        try {
+            ent = em.merge(ent);
+            fail("Allowed merge of new instance in non-cascading relation.");
+        }
+        catch (RuntimeException re) {
+            if (isActiveTx(em))
+                rollbackTx(em);
+        }
+        endEm(em);
+    }
+
+	public void testCascadeNewPersisted ()
+	{
+		CascadesEntity ent = new CascadesEntity ();
+		CascadesEntity rel1 = new CascadesEntity ();
+		CascadesEntity rel2 = new CascadesEntity ();
+		ent.setName ("ent");
+		rel1.setName ("rel1");
+		ent.setAll (rel1);
+		rel2.setName ("rel2");
+		ent.getAllCollection ().add (rel2);
+
+		OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+		startTx(em);
+		em.persist (ent);
+		endTx(em);
+		endEm(em);
+
+		CascadesEntity other1 = new CascadesEntity ();
+		CascadesEntity other2 = new CascadesEntity ();
+		other1.setName ("other1");
+		other2.setName ("other2");
+
+		ent.setAll (other1);
+		ent.getAllCollection ().remove (rel2);
+		ent.getAllCollection ().add (other2);
+
+		em = (OpenJPAEntityManager)currentEntityManager();
+		startTx(em);
+		ent = em.merge (ent);
+		assertTrue (em.isDirty (ent));
+		assertTrue (rel1 != ent.getAll ());
+		assertTrue (other1 != ent.getAll ());
+		other1 = ent.getAll ();
+		assertEquals ("other1", other1.getName ());
+		assertTrue (em.isNewlyPersistent (other1));
+		assertEquals (1, ent.getAllCollection ().size ());
+		other2 = ent.getAllCollection ().iterator ().next ();
+		assertEquals ("other2", other2.getName ());
+		assertTrue (em.isNewlyPersistent (other2));
+		endTx(em);
+		endEm(em);
+	}
+
+
+	public void testCascadesDeleteNonPersistent ()
+	{
+		CascadesEntity all = new CascadesEntity ();
+		CascadesEntity none = new CascadesEntity ();
+		CascadesEntity manyAll = new CascadesEntity ();
+		CascadesEntity manyNone = new CascadesEntity ();
+		OpenJPAEntityManager em = (OpenJPAEntityManager)currentEntityManager();
+		startTx(em);
+		em.persist (all);
+		em.persist (none);
+		em.persist (manyAll);
+		em.persist (manyNone);
+		endTx(em);
+		long allId = all.getId ();
+		long noneId = none.getId ();
+		long manyAllId = manyAll.getId ();
+		long manyNoneId = manyNone.getId ();
+		endEm(em);
+
+		em = (OpenJPAEntityManager) currentEntityManager();
+		startTx(em);
+		CascadesEntity ent = new CascadesEntity ();
+		ent.setAll (em.find (CascadesEntity.class, allId));
+		ent.setNone (em.find (CascadesEntity.class, noneId));
+		ent.getAllCollection ().add (em.find (CascadesEntity.class, manyAllId));
+		ent.getNoneCollection ().add (em.find (CascadesEntity.class, manyNoneId));
+		em.remove (ent);
+		assertTrue (em.isRemoved (ent.getAll ()));
+		assertFalse (em.isRemoved (ent.getNone ()));
+		for (CascadesEntity rel : ent.getAllCollection ())
+		assertTrue (em.isRemoved (rel));
+		for (CascadesEntity rel : ent.getNoneCollection ())
+			assertFalse (em.isRemoved (rel));
+		assertFalse (em.contains (ent));
+		endTx(em);
+		endEm(em);
+
+		em = (OpenJPAEntityManager) currentEntityManager();
+		assertNull (em.find (CascadesEntity.class, allId));
+		assertNotNull (em.find (CascadesEntity.class, noneId));
+		assertNull (em.find (CascadesEntity.class, manyAllId));
+		assertNotNull (em.find (CascadesEntity.class, manyNoneId));
+		endEm(em);
+	}
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/entityoperation/common/apps/CascadesEntity.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,112 @@
+/*
+ * 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.entityoperation.common.apps;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+
+import org.apache.openjpa.persistence.Dependent;
+
+@Entity
+public class CascadesEntity {
+
+    private long id;
+    private String name;
+    private CascadesEntity none;
+    private CascadesEntity all;
+    private CascadesEntity dependent;
+    private Collection<CascadesEntity> noneCollection = new ArrayList();
+    private Collection<CascadesEntity> allCollection = new ArrayList();
+
+    @Id
+    @GeneratedValue
+    public long getId() {
+        return this.id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    @ManyToOne
+    public CascadesEntity getNone() {
+        return this.none;
+    }
+
+    public void setNone(CascadesEntity none) {
+        this.none = none;
+    }
+
+    @ManyToOne(cascade = CascadeType.ALL)
+    public CascadesEntity getAll() {
+        return this.all;
+    }
+
+    public void setAll(CascadesEntity all) {
+        this.all = all;
+    }
+
+    @ManyToMany
+    @JoinTable(name = "CASCADES_NONE_COLL",
+        joinColumns = @JoinColumn(name = "owner"))
+    public Collection<CascadesEntity> getNoneCollection() {
+        return this.noneCollection;
+    }
+
+    public void setNoneCollection(Collection<CascadesEntity> noneCollection) {
+        this.noneCollection = noneCollection;
+    }
+
+    @ManyToMany(cascade = CascadeType.ALL)
+    @JoinTable(name = "CASCADES_ALL_COLL",
+        joinColumns = @JoinColumn(name = "owner"))
+    public Collection<CascadesEntity> getAllCollection() {
+        return this.allCollection;
+    }
+
+    public void setAllCollection(Collection<CascadesEntity> allCollection) {
+        this.allCollection = allCollection;
+    }
+
+    @ManyToOne
+    @Dependent
+    public CascadesEntity getDependent() {
+        return this.dependent;
+    }
+
+    public void setDependent(CascadesEntity dependent) {
+        this.dependent = dependent;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/JMSRemoteEventsTest.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,101 @@
+/*
+ * 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.event;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+
+import org.apache.openjpa.event.JMSRemoteCommitProvider;
+
+/**
+ * So named to prevent the autobuild from running this -- we don't
+ * have a JMS provider up and running in the autobuild currently.
+ */
+public class JMSRemoteEventsTest
+    extends RemoteEventBase {
+
+    public JMSRemoteEventsTest(String s) {
+        super(s);
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testJMSEvents() {
+        doTest(JMSRemoteCommitProvider.class,
+            "Topic=topic/KodoCommitProviderTopic",
+            "Topic=topic/KodoCommitProviderTopic");
+    }
+
+    public static void main(String[] args)
+        throws Exception {
+        Context ctx = new InitialContext();
+        TopicConnectionFactory tcf =
+            (TopicConnectionFactory) ctx.lookup("java:/ConnectionFactory");
+        Topic topic = (Topic) ctx.lookup("topic/KodoCommitProviderTopic");
+        ctx.close();
+
+        TopicConnection connection = tcf.createTopicConnection();
+
+        // false == not transacted.
+        TopicSession session = connection.createTopicSession
+            (false, Session.AUTO_ACKNOWLEDGE);
+
+        // create a subscriber.
+        TopicSubscriber s = session.createSubscriber(topic, null,
+            /* noLocal: */ false);
+        s.setMessageListener(new DebugMessageListener());
+        connection.start();
+        System.out.println
+            ("started listening on topic/KodoCommitProviderTopic");
+    }
+
+    private static class DebugMessageListener
+        implements MessageListener {
+
+        public void onMessage(Message m) {
+            try {
+                if (m instanceof ObjectMessage) {
+                    ObjectMessage om = (ObjectMessage) m;
+                    System.out.println("received object: " + om.getObject());
+                } else {
+                    System.out.println("received bad message: " + m);
+                }
+            }
+            catch (JMSException e) {
+                System.out.println("Exception while processing message");
+                e.printStackTrace(System.out);
+            }
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/RemoteEventBase.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,249 @@
+/*
+ * 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.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.StoreCache;
+import org.apache.openjpa.util.Id;
+
+public class RemoteEventBase extends AbstractTestCase {
+
+    public Id roid;
+    public StoreCache datacatch;
+
+    public RemoteEventBase(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+        datacatch.evictAll();
+    }
+
+    public void tearDown() throws Exception {
+        ((OpenJPAEntityManagerSPI) OpenJPAPersistence
+            .cast(currentEntityManager())).getConfiguration()
+            .getRemoteCommitEventManager().close();
+    }
+
+    protected void doTest(Class providerClass, String classProps1,
+        String classProps2) {
+        String transmit = "TransmitPersistedObjectIds=true";
+        if (classProps1 == null || classProps1.length() == 0)
+            classProps1 = transmit;
+        else
+            classProps1 += "," + transmit;
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.RemoteCommitProvider",
+            Configurations.getPlugin(providerClass.getName(), classProps1));
+        propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup1");
+        propsMap.put("openjpa.DataCache", "true");
+        OpenJPAEntityManagerFactory factory1 = getEmf(propsMap);
+
+        TriggerRemoteCommitListener listener1 =
+            new TriggerRemoteCommitListener();
+        ((OpenJPAEntityManagerFactorySPI) factory1).getConfiguration()
+            .getRemoteCommitEventManager().addListener(listener1);
+
+        if (classProps2 == null || classProps2.length() == 0)
+            classProps2 = transmit;
+        else
+            classProps2 += ", " + transmit;
+
+        propsMap = new HashMap();
+        propsMap.put("openjpa.RemoteCommitProvider",
+            Configurations.getPlugin(providerClass.getName(), classProps2));
+        propsMap.put("openjpa.FetchGroups", "differentiatingFetchGroup2");
+        propsMap.put("openjpa.DataCache", "true");
+        OpenJPAEntityManagerFactory factory2 = getEmf(propsMap);
+
+        RemoteCommitListenerTestImpl listener2 =
+            new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) factory2).getConfiguration()
+            .getRemoteCommitEventManager().addListener(listener2);
+
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) factory1.createEntityManager();
+        datacatch = pm.getEntityManagerFactory().getStoreCache();
+        // get an object id
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        pm.persist(t1);
+        Object oid = pm.getObjectId(t1);
+        roid = Id.newInstance(RuntimeTest1.class, oid);
+        endTx(pm);
+
+        try {
+            Thread.currentThread().sleep(250);
+        }
+        catch (InterruptedException ie) {
+        }
+
+        // ensure that the commit info was not propagated to factory1.
+        assertFalse(listener1.commitNotificationReceived);
+
+        // ensure that the commit info propagated to the
+        // factories correctly.
+        assertNotNull(listener2.added);
+        assertNotNull(listener2.updated);
+        assertNotNull(listener2.deleted);
+
+        boolean pass = false;
+        for (Iterator iter = listener2.added.iterator(); iter.hasNext();) {
+            Id roid = Id.newInstance(RuntimeTest1.class, oid);
+            Id it = (Id) iter.next();
+            System.out.println("===ROID: " + roid.getId() + " +++== ITER: " +
+                it.getId() + " Content: " + listener2.added + "ROID Cont: " +
+                roid);
+            System.out.println("Result of COMP " + it.equals(roid));
+            //FixMe --det. why it.equals(roid) fails when the are actually equal
+            if (it.toString().equals(roid.toString())) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue("pass = " + pass, pass);
+        assertTrue(listener2.updated.size() == 0);
+        assertTrue(listener2.deleted.size() == 0);
+
+        // modify an object
+        startTx(pm);
+        t1.setStringField("baz");
+        endTx(pm);
+
+        try {
+            Thread.currentThread().sleep(250);
+        }
+        catch (InterruptedException ie) {
+        }
+
+        // ensure that the commit info was not propagated to factory1.
+        assertFalse(listener1.commitNotificationReceived);
+
+        // ensure that the commit info propagated to the remote
+        // factories correctly.
+        assertNotNull(listener2.added);
+        assertNotNull(listener2.updated);
+        assertNotNull(listener2.deleted);
+
+        pass = false;
+        for (Iterator iter = listener2.updated.iterator(); iter.hasNext();) {
+            Id it = (Id) iter.next();
+            System.out.println("===ROID: " + roid.getId() + "+++== ITER: " +
+                it.getId() + "Content: " + listener2.added);
+            System.out.println("Result of COMP " + it.equals(roid));
+
+            if (it.toString().equals(roid.toString())) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(listener2.added.size() == 0);
+        assertTrue(listener2.deleted.size() == 0);
+
+        // delete an object
+        startTx(pm);
+        pm.remove(t1);
+        endTx(pm);
+
+        try {
+            Thread.currentThread().sleep(250);
+        }
+        catch (InterruptedException ie) {
+        }
+
+        // ensure that the commit info was not propagated to factory1.
+        assertFalse(listener1.commitNotificationReceived);
+
+        // ensure that the commit info propagated to the remote
+        // factories correctly.
+        assertNotNull(listener2.added);
+        assertNotNull(listener2.updated);
+        assertNotNull(listener2.deleted);
+
+        pass = false;
+        for (Iterator iter = listener2.deleted.iterator(); iter.hasNext();) {
+            Id it = (Id) iter.next();
+            System.out.println("===ROID: " + roid.getId() + "+++== ITER: " +
+                it.getId() + "Content: " + listener2.added);
+            System.out.println("Result of COMP " + it.equals(roid));
+
+            if (it.toString().equals(roid.toString())) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(listener2.added.size() == 0);
+        assertTrue(listener2.updated.size() == 0);
+    }
+
+    protected static class RemoteCommitListenerTestImpl implements
+        RemoteCommitListener {
+
+        transient Collection added;
+
+        transient Collection updated;
+
+        transient Collection deleted;
+
+        public void afterCommit(RemoteCommitEvent event) {
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+        }
+
+        public void close() {
+        }
+    }
+
+    protected static class TriggerRemoteCommitListener
+        implements RemoteCommitListener {
+
+        boolean commitNotificationReceived = false;
+
+        public void afterCommit(RemoteCommitEvent event) {
+            commitNotificationReceived = true;
+        }
+
+        public void close() {
+        }
+    }
+}
+// looks like this might be creating another factory that is
+// connecting to the same ports, causing the failure. Should
+// probably debug by putting a third conf in RemoteEventBase.

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestEvents.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,256 @@
+/*
+ * 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.event;
+
+import java.util.Collection;
+import java.util.Collections;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import junit.framework.AssertionFailedError;
+
+import org.apache.openjpa.event.TransactionEvent;
+import org.apache.openjpa.event.TransactionListener;
+import org.apache.openjpa.persistence.CallbackMode;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+
+public class TestEvents
+    extends AbstractTestCase {
+
+    private TransactionEventListenerTestImpl transactionListener;
+
+    public TestEvents(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        transactionListener = new TransactionEventListenerTestImpl();
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testCommit() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+
+        assertEquals(0, transactionListener.status);
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+
+        pm.persist(t1);
+
+        endTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.COMMITTED,
+            transactionListener.status);
+    }
+
+    public void testRollback() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+
+        assertEquals(0, transactionListener.status);
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+
+        pm.persist(t1);
+
+        rollbackTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.ROLLEDBACK,
+            transactionListener.status);
+    }
+
+    public void testObjectChanges() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+
+        // add a couple new object
+        RuntimeTest1 t1 = new RuntimeTest1("t1", 0);
+        RuntimeTest1 t2 = new RuntimeTest1("t2", 1);
+        startTx(pm);
+        pm.persist(t1);
+        pm.persist(t2);
+        endTx(pm);
+
+        // now do some modifications
+        transactionListener.status = 0;
+        startTx(pm);
+        RuntimeTest1 t3 = new RuntimeTest1("t3", 3);
+        pm.persist(t3);
+        t1.setStringField("baz");
+        pm.remove(t2);
+        endTx(pm);
+
+        assertEquals(3, transactionListener.trans.size());
+        assertTrue(transactionListener.trans.contains(t1));
+        assertTrue(transactionListener.trans.contains(t2));
+        assertTrue(transactionListener.trans.contains(t3));
+    }
+
+    public void testIgnoreCallbackModeExceptionConsumed() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+        //FIXME need to find an alternative
+        ((OpenJPAEntityManagerSPI) pm)
+            .setTransactionListenerCallbackMode(CallbackMode.IGNORE);
+        transactionListener.exception = transactionListener.EXCEPTION;
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+        pm.persist(t1);
+        endTx(pm);
+        endEm(pm);
+
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.COMMITTED,
+            transactionListener.status);
+    }
+
+    public void testExceptionCausesRollback() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+        transactionListener.exception = transactionListener.EXCEPTION;
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+        pm.persist(t1);
+
+        try {
+            endTx(pm);
+            fail("Commit should have caused exception.");
+        } catch (AssertionFailedError afe) {
+            bug(1139, afe, "Listener exceptions being swallowed");
+            return;
+        } catch (Exception je) {
+            assertEquals("xxx", je.getMessage());
+        }
+        assertTrue(!(isActiveTx(pm)));
+        endEm(pm);
+
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.ROLLEDBACK,
+            transactionListener.status);
+    }
+
+    public void testExceptionAfterCommitThrown() {
+        OpenJPAEntityManager pm =
+            (OpenJPAEntityManager) currentEntityManager();
+        ((OpenJPAEntityManagerSPI) pm)
+            .addTransactionListener(transactionListener);
+        transactionListener.exception = transactionListener.EXCEPTION_AFTER;
+
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        assertEquals(TransactionEventListenerTestImpl.STARTED,
+            transactionListener.status);
+        pm.persist(t1);
+
+        try {
+            endTx(pm);
+            fail("Commit should have caused exception.");
+        } catch (AssertionFailedError afe) {
+            bug(1139, afe, "Listener exceptions being swallowed");
+        } catch (Exception je) {
+            assertEquals("xxx", je.getMessage());
+        }
+        assertFalse(isActiveTx(pm));
+        endEm(pm);
+
+        assertEquals(TransactionEventListenerTestImpl.STARTED |
+            TransactionEventListenerTestImpl.COMMIT_BEGUN |
+            TransactionEventListenerTestImpl.COMMITTED,
+            transactionListener.status);
+    }
+
+    private static class TransactionEventListenerTestImpl
+        implements TransactionListener {
+
+        static int STARTED = 1;
+        static int COMMITTED = 2;
+        static int ROLLEDBACK = 4;
+        static int COMMIT_BEGUN = 8;
+        static int EXCEPTION = 1;
+        static int EXCEPTION_AFTER = 2;
+
+        int exception;
+        int status;
+        Collection trans = Collections.EMPTY_LIST;
+
+        public void afterBegin(TransactionEvent event) {
+            status |= STARTED;
+        }
+
+        public void beforeFlush(TransactionEvent event) {
+        }
+
+        public void afterFlush(TransactionEvent event) {
+        }
+
+        public void beforeCommit(TransactionEvent event) {
+            status |= COMMIT_BEGUN;
+            trans = event.getTransactionalObjects();
+            if (exception == EXCEPTION)
+                throw new RuntimeException("xxx");
+        }
+
+        public void afterCommit(TransactionEvent event) {
+            status |= COMMITTED;
+            if (exception == EXCEPTION_AFTER)
+                throw new RuntimeException("xxx");
+        }
+
+        public void afterRollback(TransactionEvent event) {
+            status |= ROLLEDBACK;
+        }
+
+        public void afterStateTransitions(TransactionEvent event) {
+        }
+
+        public void afterCommitComplete(TransactionEvent event) {
+        }
+
+        public void afterRollbackComplete(TransactionEvent event) {
+        }
+    }
+}
\ No newline at end of file

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestFakeRemoteEvents.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,226 @@
+/*
+ * 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.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+
+import org.apache.openjpa.event.AbstractRemoteCommitProvider;
+import org.apache.openjpa.event.RemoteCommitEvent;
+import org.apache.openjpa.event.RemoteCommitListener;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.util.Id;
+
+public class TestFakeRemoteEvents extends AbstractTestCase {
+
+    /*
+      * The most recently set provider, and a lock to control access to it. This
+      * is rather hacky.
+      */
+    private static Object currentProviderLock = new Object();
+
+    private static RemoteCommitProviderTestImpl currentProvider;
+
+    public TestFakeRemoteEvents(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void setUp() {
+        deleteAll(RuntimeTest1.class);
+    }
+
+    public void testListener() {
+
+        Map propsMap = new HashMap();
+        propsMap.put("openjpa.RemoteCommitProvider", "sjvm");
+        propsMap.put("openjpa.DataCache", "true");
+        OpenJPAEntityManagerFactory factory = getEmf(propsMap);
+
+        RemoteCommitListenerTestImpl transactionListener =
+            new RemoteCommitListenerTestImpl();
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().addListener(
+            transactionListener);
+
+        OpenJPAEntityManager pm = (OpenJPAEntityManager) factory
+            .createEntityManager();
+
+        // get an object id
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        pm.persist(t1);
+        Object oid = pm.getObjectId(t1);
+        rollbackTx(pm);
+
+        // simulate an add
+        Set s = new HashSet();
+        s.add(oid);
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().fireEvent(
+            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
+                s, null, null, null));
+
+        boolean pass = false;
+        for (Iterator iter = transactionListener.added.iterator(); iter
+            .hasNext();) {
+            if (iter.next().equals(oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(transactionListener.updated.size() == 0);
+        assertTrue(transactionListener.deleted.size() == 0);
+
+        // simulate modifications
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().fireEvent(
+            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
+                null, null, s, null));
+
+        pass = false;
+        for (Iterator iter = transactionListener.updated.iterator(); iter
+            .hasNext();) {
+            if (iter.next().equals(oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(transactionListener.added.size() == 0);
+        assertTrue(transactionListener.deleted.size() == 0);
+
+        // simulate a delete
+        ((OpenJPAEntityManagerFactorySPI) factory).getConfiguration()
+            .getRemoteCommitEventManager().fireEvent(
+            new RemoteCommitEvent(RemoteCommitEvent.PAYLOAD_OIDS_WITH_ADDS,
+                null, null, null, s));
+
+        pass = false;
+        for (Iterator iter = transactionListener.deleted.iterator(); iter
+            .hasNext();) {
+            if (iter.next().equals(oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(transactionListener.added.size() == 0);
+        assertTrue(transactionListener.updated.size() == 0);
+    }
+
+    public void testProvider() {
+        RemoteCommitProviderTestImpl provider;
+        OpenJPAEntityManager pm;
+        synchronized (currentProviderLock) {
+            Map propsMap = new HashMap();
+            propsMap.put("openjpa.RemoteCommitProvider",
+                RemoteCommitProviderTestImpl.class.getName()
+                    + "(TransmitPersistedObjectIds=true)");
+            propsMap.put("openjpa.DataCache", "true");
+            OpenJPAEntityManagerFactory factory = getEmf(propsMap);
+
+            pm = (OpenJPAEntityManager) factory.createEntityManager();
+            provider = currentProvider;
+        }
+
+        // get an object id
+        RuntimeTest1 t1 = new RuntimeTest1("foo", 5);
+        startTx(pm);
+        pm.persist(t1);
+        Object oid = pm.getObjectId(t1);
+        endTx(pm);
+
+        boolean pass = false;
+        for (Iterator iter = provider.added.iterator(); iter.hasNext();) {
+            Object added = iter.next();
+            if (equals(added, oid)) {
+                pass = true;
+                break;
+            }
+        }
+        assertTrue(pass);
+        assertTrue(provider.updated.size() == 0);
+        assertTrue(provider.deleted.size() == 0);
+    }
+
+    boolean equals(Object added, Object oid) {
+        if (added.equals(oid))
+            return true;
+        if (added instanceof Id)
+            return ((Id) added).getIdObject().equals(oid);
+        return false;
+    }
+
+    private static class RemoteCommitListenerTestImpl implements
+        RemoteCommitListener {
+
+        transient Collection added;
+
+        transient Collection updated;
+
+        transient Collection deleted;
+
+        public void afterCommit(RemoteCommitEvent event) {
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+        }
+
+        public void close() {
+        }
+    }
+
+    public static class RemoteCommitProviderTestImpl extends
+        AbstractRemoteCommitProvider {
+
+        Collection added;
+
+        Collection updated;
+
+        Collection deleted;
+
+        public RemoteCommitProviderTestImpl() {
+            synchronized (currentProviderLock) {
+                currentProvider = this;
+            }
+        }
+
+        // ---------- RemoteCommitProvider implementation ----------
+
+        public void broadcast(RemoteCommitEvent event) {
+            this.added = event.getPersistedObjectIds();
+            this.updated = event.getUpdatedObjectIds();
+            this.deleted = event.getDeletedObjectIds();
+        }
+
+        public void close() {
+        }
+    }
+}

Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java?rev=627979&view=auto
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java (added)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/event/TestLifecycleEventManager.java Fri Feb 15 01:19:55 2008
@@ -0,0 +1,222 @@
+/*
+ * 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.event;
+
+
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest1;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest2;
+import org.apache.openjpa.persistence.event.common.apps.RuntimeTest4;
+import org.apache.openjpa.persistence.common.utils.AbstractTestCase;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.LifecycleEventManager;
+import org.apache.openjpa.event.LoadListener;
+import org.apache.openjpa.event.StoreListener;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.MetaDataRepository;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+
+/**
+ * <p>Test the {@link LifecycleEventManager}.</p>
+ *
+ * @author Abe White
+ */
+public class TestLifecycleEventManager
+    extends AbstractTestCase {
+
+    public TestLifecycleEventManager(String s) {
+        super(s, "eventcactusapp");
+    }
+
+    public void testAllClassListener() {
+        MetaDataRepository repos =
+            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
+                OpenJPAPersistence.createEntityManagerFactory("TestConv2", "")))
+                .
+                    getConfiguration().getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getMetaData(RuntimeTest2.class, null, true);
+        LifecycleEventManager mgr = new LifecycleEventManager();
+        RuntimeTest2 pc = new RuntimeTest2();
+        Listener listener = new Listener();
+
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+
+        mgr.addListener(listener, null);
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+
+        Listener listener2 = new Listener();
+        mgr.addListener(listener2, null);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(1, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(0, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.removeListener(listener2);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(2, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(0, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(2, listener.load);
+        assertEquals(1, listener.store);
+        assertEquals(0, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.BEFORE_STORE);
+        assertEquals(2, listener.load);
+        assertEquals(2, listener.store);
+        assertEquals(1, listener.preStore);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_DIRTY);
+        assertEquals(2, listener.load);
+        assertEquals(2, listener.store);
+
+        mgr.removeListener(listener);
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(2, listener.load);
+        assertEquals(2, listener.store);
+    }
+
+    public void testBaseClassListener() {
+        MetaDataRepository repos =
+            ((OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.cast(
+                OpenJPAPersistence.createEntityManagerFactory("TestConv2", "")))
+                .
+                    getConfiguration().getMetaDataRepositoryInstance();
+        ClassMetaData meta = repos.getMetaData(RuntimeTest2.class, null, true);
+
+        LifecycleEventManager mgr = new LifecycleEventManager();
+        RuntimeTest2 pc = new RuntimeTest2();
+        Listener listener = new Listener();
+
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+
+        mgr.addListener(listener, new Class[]{ RuntimeTest1.class });
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+        assertFalse(mgr.hasLoadListeners(new RuntimeTest4("foo"), meta));
+        assertEquals(0, listener.load);
+        assertEquals(0, listener.store);
+
+        Listener listener2 = new Listener();
+        mgr.addListener(listener2, new Class[]{ RuntimeTest2.class });
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+        assertFalse(mgr.hasDirtyListeners(pc, meta));
+        assertFalse(mgr.hasLoadListeners(new RuntimeTest4("foo"), meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(1, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(1, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(2, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(2, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(new RuntimeTest1(), meta, LifecycleEvent.AFTER_LOAD);
+        assertEquals(3, listener.load);
+        assertEquals(0, listener.store);
+        assertEquals(2, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.removeListener(listener2);
+        assertTrue(mgr.hasLoadListeners(pc, meta));
+        assertTrue(mgr.hasStoreListeners(pc, meta));
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+        assertEquals(2, listener2.load);
+        assertEquals(0, listener2.store);
+
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_DIRTY);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+
+        mgr.fireEvent(new RuntimeTest4("foo"), meta,
+            LifecycleEvent.AFTER_STORE);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+
+        mgr.removeListener(listener);
+        assertFalse(mgr.hasLoadListeners(pc, meta));
+        assertFalse(mgr.hasStoreListeners(pc, meta));
+        mgr.fireEvent(pc, meta, LifecycleEvent.AFTER_STORE);
+        assertEquals(3, listener.load);
+        assertEquals(1, listener.store);
+    }
+
+    private static class Listener
+        implements LoadListener, StoreListener {
+
+        public int load = 0;
+        public int preStore = 0;
+        public int store = 0;
+
+        public void afterLoad(LifecycleEvent ev) {
+            load++;
+        }
+
+        public void afterRefresh(LifecycleEvent ev) {
+            // TODO
+        }
+
+        public void beforeStore(LifecycleEvent ev) {
+            preStore++;
+            store++;
+        }
+
+        public void afterStore(LifecycleEvent ev) {
+            store++;
+        }
+    }
+}



Mime
View raw message