You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by al...@apache.org on 2012/03/29 21:43:04 UTC

svn commit: r1307075 - in /openjpa/branches/2.2.x: openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persiste...

Author: allee8285
Date: Thu Mar 29 19:43:04 2012
New Revision: 1307075

URL: http://svn.apache.org/viewvc?rev=1307075&view=rev
Log:
OPENJPA-2163 Clone trunk commit to 2.2.x

Added:
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/AddListenerEntity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerInEntity.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PerInstanceListener.java   (with props)
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMultiEmEntityListeners.java   (with props)
Modified:
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/validation/TestValidationMode.java
    openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml
    openjpa/branches/2.2.x/openjpa-project/src/doc/manual/ref_guide_conf.xml

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=1307075&r1=1307074&r2=1307075&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java Thu Mar 29 19:43:04 2012
@@ -74,7 +74,7 @@ public class Compatibility {
     private boolean _useListAttributeForArrays = false; 
     private boolean _metaFactoriesAreStrict = false; 
     private boolean _resetFlushFlagForCascadePersist = true;//OPENJPA-2051
-
+    private boolean _singletonLifecycleEventManager = false;
     
     /**
      * Whether to require exact identity value types when creating object
@@ -696,4 +696,21 @@ public class Compatibility {
     public void setResetFlushFlagForCascadePersist(boolean b){
         _resetFlushFlagForCascadePersist = b;
     }
+
+    /**
+     * Returns true if life cycle event manager is a singleton configuration.
+     */
+    public boolean isSingletonLifecycleEventManager() {
+        return _singletonLifecycleEventManager;
+    }
+
+    /**
+     * This property set whether each EntityManager has its own life cycle event manager.
+       By default, each EntityManager only fires events to the registered listeners to the entities
+       it manages. If the life cycle event manager is a singleton, events will be fired to listeners
+       registered to all instances of EntityManager in the same persistence unit.
+     */
+    public void setSingletonLifecycleEventManager(boolean singleton) {
+        _singletonLifecycleEventManager = singleton;
+    }
 }

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java?rev=1307075&r1=1307074&r2=1307075&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/OpenJPAConfigurationImpl.java Thu Mar 29 19:43:04 2012
@@ -68,7 +68,6 @@ import org.apache.openjpa.lib.encryption
 import org.apache.openjpa.lib.instrumentation.InstrumentationLevel;
 import org.apache.openjpa.lib.instrumentation.InstrumentationProvider;
 import org.apache.openjpa.lib.log.Log;
-import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.meta.MetaDataFactory;
 import org.apache.openjpa.meta.MetaDataRepository;
 import org.apache.openjpa.util.ClassResolver;
@@ -88,7 +87,7 @@ public class OpenJPAConfigurationImpl
     extends ConfigurationImpl
     implements OpenJPAConfiguration {
 
-    private static final Localizer _loc = Localizer.forPackage(OpenJPAConfigurationImpl.class);
+    // private static final Localizer _loc = Localizer.forPackage(OpenJPAConfigurationImpl.class);
 
     // cached state; some of this is created in getter methods, so make
     // protected in case subclasses want to access without creating
@@ -1749,9 +1748,9 @@ public class OpenJPAConfigurationImpl
     }
 
     public LifecycleEventManager getLifecycleEventManagerInstance() {
-        LifecycleEventManager lem = (LifecycleEventManager)
-            lifecycleEventManager.get();
-        if (lem == null) {
+        LifecycleEventManager lem = null;
+        if (!getCompatibilityInstance().isSingletonLifecycleEventManager() ||
+                (lem = (LifecycleEventManager)lifecycleEventManager.get()) == null) {
             lem = (LifecycleEventManager)lifecycleEventManager
                 .instantiate(LifecycleEventManager.class, this);
         }

Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/AddListenerEntity.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/AddListenerEntity.java?rev=1307075&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/AddListenerEntity.java (added)
+++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/AddListenerEntity.java Thu Mar 29 19:43:04 2012
@@ -0,0 +1,47 @@
+/*
+ * 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.callbacks;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+@Entity
+public class AddListenerEntity {
+    @Id @GeneratedValue
+    private long id;
+
+    private int value;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public void setValue(int value) {
+        this.value = value;
+    }
+}

Propchange: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/AddListenerEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerInEntity.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerInEntity.java?rev=1307075&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerInEntity.java (added)
+++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerInEntity.java Thu Mar 29 19:43:04 2012
@@ -0,0 +1,97 @@
+/*
+ * 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.callbacks;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+
+@Entity
+public class ListenerInEntity {
+    @Id @GeneratedValue
+    private long id;
+
+    private int value;
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public void setValue(int value) {
+        this.value = value;
+    }
+
+    transient int prePersistCount;
+    transient int postPersistCount;
+    transient int preUpdateCount;
+    transient int postUpdateCount;
+    transient int preRemoveCount;
+    transient int postRemoveCount;
+    transient int postLoadCount;
+
+    @PrePersist
+    public void prePersist() {
+        prePersistCount++;
+    }
+
+    @PostPersist
+    public void postPersist() {
+        postPersistCount++;
+    }
+
+    @PostLoad
+    public void postLoad() {
+        postLoadCount++;
+    }
+
+    @PreUpdate
+    public void preUpdate() {
+        preUpdateCount++;
+    }
+
+    @PostUpdate
+    public void postUpdate() {
+        postUpdateCount++;
+    }
+
+    @PreRemove
+    public void preRemove() {
+        preRemoveCount++;
+    }
+
+    @PostRemove
+    public void postRemove() {
+        postRemoveCount++;
+    }
+}

Propchange: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/ListenerInEntity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PerInstanceListener.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PerInstanceListener.java?rev=1307075&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PerInstanceListener.java (added)
+++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PerInstanceListener.java Thu Mar 29 19:43:04 2012
@@ -0,0 +1,115 @@
+/*
+ * 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.callbacks;
+
+import org.apache.openjpa.event.DeleteListener;
+import org.apache.openjpa.event.DirtyListener;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.LoadListener;
+import org.apache.openjpa.event.PersistListener;
+import org.apache.openjpa.event.PostDeleteListener;
+import org.apache.openjpa.event.PostPersistListener;
+import org.apache.openjpa.event.StoreListener;
+
+public class PerInstanceListener implements PersistListener, DeleteListener, DirtyListener,
+        LoadListener, StoreListener, PostPersistListener, PostDeleteListener {
+
+    int beforeStore;
+    int afterStore;
+    int afterLoad;
+    int afterRefresh;
+    int beforeDirty;
+    int afterDirty;
+    int beforeDirtyFlushed;
+    int afterDirtyFlushed;
+    int beforeDelete;
+    int afterDelete;
+    int beforePersist;
+    int afterPersist;
+
+    @Override
+    public void afterDeletePerformed(LifecycleEvent event) {
+        afterDelete++;
+    }
+
+    @Override
+    public void afterPersistPerformed(LifecycleEvent event) {
+        afterPersist++;
+    }
+
+    @Override
+    public void beforeStore(LifecycleEvent event) {
+        beforeStore++;
+    }
+
+    @Override
+    public void afterStore(LifecycleEvent event) {
+        afterStore++;
+    }
+
+    @Override
+    public void afterLoad(LifecycleEvent event) {
+        afterLoad++;
+    }
+
+    @Override
+    public void afterRefresh(LifecycleEvent event) {
+        afterRefresh++;
+    }
+
+    @Override
+    public void beforeDirty(LifecycleEvent event) {
+        beforeDirty++;
+    }
+
+    @Override
+    public void afterDirty(LifecycleEvent event) {
+        afterDirty++;
+    }
+
+    @Override
+    public void beforeDirtyFlushed(LifecycleEvent event) {
+        beforeDirtyFlushed++;
+    }
+
+    @Override
+    public void afterDirtyFlushed(LifecycleEvent event) {
+        afterDirtyFlushed++;
+    }
+
+    @Override
+    public void beforeDelete(LifecycleEvent event) {
+        beforeDelete++;
+    }
+
+    @Override
+    public void afterDelete(LifecycleEvent event) {
+        afterDelete++;
+    }
+
+    @Override
+    public void beforePersist(LifecycleEvent event) {
+        beforePersist++;
+    }
+
+    @Override
+    public void afterPersist(LifecycleEvent event) {
+        afterPersist++;
+    }
+}

Propchange: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/PerInstanceListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMultiEmEntityListeners.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMultiEmEntityListeners.java?rev=1307075&view=auto
==============================================================================
--- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMultiEmEntityListeners.java (added)
+++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMultiEmEntityListeners.java Thu Mar 29 19:43:04 2012
@@ -0,0 +1,241 @@
+/*
+ * 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.callbacks;
+
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+public class TestMultiEmEntityListeners extends SingleEMFTestCase {
+
+    public void setUp() {
+        setUp(CLEAR_TABLES, ListenerInEntity.class, AddListenerEntity.class
+//                , "openjpa.Compatibility", "SingletonLifecycleEventManager=true"
+            );
+    }
+
+    public void testListenerInEntity1() {
+        OpenJPAEntityManager em1 = null;
+        OpenJPAEntityManager em2 = null;
+        try {
+            em1 = emf.createEntityManager();
+            em2 = emf.createEntityManager();
+
+            ListenerInEntity o1 = new ListenerInEntity();
+            ListenerInEntity o2 = new ListenerInEntity();
+
+            em1.getTransaction().begin();
+            em1.persist(o1);
+            assertListenerInEntityStatus(o1, 1, 0, 0, 0, 0, 0, 0);
+            assertListenerInEntityStatus(o2, 0, 0, 0, 0, 0, 0, 0);
+
+            em2.getTransaction().begin();
+            em2.persist(o2);
+            assertListenerInEntityStatus(o1, 1, 0, 0, 0, 0, 0, 0);
+            assertListenerInEntityStatus(o2, 1, 0, 0, 0, 0, 0, 0);
+
+            em2.getTransaction().commit();
+            long id2 = o2.getId();
+            assertListenerInEntityStatus(o1, 1, 0, 0, 0, 0, 0, 0);
+            assertListenerInEntityStatus(o2, 1, 1, 0, 0, 0, 0, 0);
+
+            em1.getTransaction().commit();
+            long id1 = o1.getId();
+            assertListenerInEntityStatus(o1, 1, 1, 0, 0, 0, 0, 0);
+            assertListenerInEntityStatus(o2, 1, 1, 0, 0, 0, 0, 0);
+
+            em1.clear();
+            ListenerInEntity fo1 = em1.find(ListenerInEntity.class, id1);
+            assertNotNull(fo1);
+            assertListenerInEntityStatus(fo1, 0, 0, 0, 0, 0, 0, 1);
+
+            em2.clear();
+            ListenerInEntity fo2 = em2.find(ListenerInEntity.class, id2);
+            assertNotNull(fo2);
+            assertListenerInEntityStatus(fo1, 0, 0, 0, 0, 0, 0, 1);
+            assertListenerInEntityStatus(fo2, 0, 0, 0, 0, 0, 0, 1);
+
+            em1.getTransaction().begin();
+            fo1.setValue(fo1.getValue() + 1);
+
+            em1.flush();
+            assertListenerInEntityStatus(fo1, 0, 0, 1, 1, 0, 0, 1);
+            assertListenerInEntityStatus(fo2, 0, 0, 0, 0, 0, 0, 1);
+
+            em2.getTransaction().begin();
+            fo2.setValue(fo2.getValue() + 1);
+
+            em2.flush();
+            assertListenerInEntityStatus(fo1, 0, 0, 1, 1, 0, 0, 1);
+            assertListenerInEntityStatus(fo2, 0, 0, 1, 1, 0, 0, 1);
+
+            em1.remove(fo1);
+            assertListenerInEntityStatus(fo1, 0, 0, 1, 1, 1, 0, 1);
+            assertListenerInEntityStatus(fo2, 0, 0, 1, 1, 0, 0, 1);
+
+            em2.remove(fo2);
+            assertListenerInEntityStatus(fo1, 0, 0, 1, 1, 1, 0, 1);
+            assertListenerInEntityStatus(fo2, 0, 0, 1, 1, 1, 0, 1);
+
+            em1.getTransaction().commit();
+
+            assertListenerInEntityStatus(fo1, 0, 0, 1, 1, 1, 1, 1);
+            assertListenerInEntityStatus(fo2, 0, 0, 1, 1, 1, 0, 1);
+
+            em2.getTransaction().commit();
+
+            assertListenerInEntityStatus(fo1, 0, 0, 1, 1, 1, 1, 1);
+            assertListenerInEntityStatus(fo2, 0, 0, 1, 1, 1, 1, 1);
+
+            em1.close();
+            em2.close();
+        } finally {
+            if (em1 != null && em1.getTransaction().isActive())
+                em1.getTransaction().rollback();
+            if (em1 != null && em1.isOpen())
+                em1.close();
+            if (em2 != null && em2.getTransaction().isActive())
+                em2.getTransaction().rollback();
+            if (em2 != null && em2.isOpen())
+                em2.close();
+        }
+    }
+
+    private void assertListenerInEntityStatus(ListenerInEntity l,
+        int prePersist, int postPersist,
+        int preUpdate, int postUpdate,
+        int preRemove, int postRemove,
+        int postLoad) {
+        assertEquals(prePersist, l.prePersistCount);
+        assertEquals(postPersist, l.postPersistCount);
+        assertEquals(preUpdate, l.preUpdateCount);
+        assertEquals(postUpdate, l.postUpdateCount);
+        assertEquals(preRemove, l.preRemoveCount);
+        assertEquals(postRemove, l.postRemoveCount);
+        assertEquals(postLoad, l.postLoadCount);
+    }
+
+    public void testAddListenerEntity1() {
+        OpenJPAEntityManager em1 = null;
+        OpenJPAEntityManager em2 = null;
+        try {
+            em1 = emf.createEntityManager();
+            PerInstanceListener l1 = new PerInstanceListener();
+            ((OpenJPAEntityManagerSPI) em1).addLifecycleListener(l1, (Class<?>[])null);
+
+            em2 = emf.createEntityManager();
+            PerInstanceListener l2 = new PerInstanceListener();
+            ((OpenJPAEntityManagerSPI) em2).addLifecycleListener(l2, (Class<?>[])null);
+
+            AddListenerEntity o1 = new AddListenerEntity();
+            AddListenerEntity o2 = new AddListenerEntity();
+
+            em1.getTransaction().begin();
+            em1.persist(o1);
+            assertAddListenerEntityStatus(l1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
+            assertAddListenerEntityStatus(l2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+            em2.getTransaction().begin();
+            em2.persist(o2);
+            assertAddListenerEntityStatus(l1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
+
+            em2.getTransaction().commit();
+            assertAddListenerEntityStatus(l1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0);
+            long id2 = o2.getId();
+
+            em1.getTransaction().commit();
+            assertAddListenerEntityStatus(l1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0);
+            long id1 = o1.getId();
+
+            em1.clear();
+            AddListenerEntity fo1 = em1.find(AddListenerEntity.class, id1);
+            assertAddListenerEntityStatus(l1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0);
+            assertNotNull(fo1);
+
+            em2.clear();
+            AddListenerEntity fo2 = em2.find(AddListenerEntity.class, id2);
+            assertAddListenerEntityStatus(l1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
+            assertNotNull(fo2);
+
+            em1.getTransaction().begin();
+            fo1.setValue(fo1.getValue() + 1);
+            assertAddListenerEntityStatus(l1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
+
+            em1.flush();
+            assertAddListenerEntityStatus(l1, 1, 1, 2, 2, 1, 0, 1, 1, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0);
+
+            em2.getTransaction().begin();
+            fo2.setValue(fo2.getValue() + 1);
+            assertAddListenerEntityStatus(l1, 1, 1, 2, 2, 1, 0, 1, 1, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0);
+
+            em2.flush();
+            assertAddListenerEntityStatus(l1, 1, 1, 2, 2, 1, 0, 1, 1, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 2, 2, 1, 0, 1, 1, 0, 0);
+
+            em2.remove(fo2);
+            assertAddListenerEntityStatus(l1, 1, 1, 2, 2, 1, 0, 1, 1, 0, 0);
+            assertAddListenerEntityStatus(l2, 1, 1, 2, 2, 1, 0, 1, 1, 1, 1);
+
+            em1.remove(fo1);
+            assertAddListenerEntityStatus(l1, 1, 1, 2, 2, 1, 0, 1, 1, 1, 1);
+            assertAddListenerEntityStatus(l2, 1, 1, 2, 2, 1, 0, 1, 1, 1, 1);
+
+            em1.getTransaction().commit();
+            em2.getTransaction().commit();
+
+            em1.close();
+            em2.close();
+        } finally {
+            if (em1 != null && em1.getTransaction().isActive())
+                em1.getTransaction().rollback();
+            if (em1 != null && em1.isOpen())
+                em1.close();
+            if (em2 != null && em2.getTransaction().isActive())
+                em2.getTransaction().rollback();
+            if (em2 != null && em2.isOpen())
+                em2.close();
+        }
+    }
+
+    private void assertAddListenerEntityStatus(PerInstanceListener l
+            , int beforePersist, int afterPersist
+            , int beforeStore, int afterStore
+            , int afterLoad, int afterRefresh
+            , int beforeDirty, int afterDirty
+            , int beforeDelete, int afterDelete) {
+        assertEquals(beforePersist, l.beforePersist);
+        assertEquals(afterPersist, l.afterPersist);
+        assertEquals(beforeStore, l.beforeStore);
+        assertEquals(afterStore, l.afterStore);
+        assertEquals(afterLoad, l.afterLoad);
+        assertEquals(afterRefresh, l.afterRefresh);
+        assertEquals(beforeDirty, l.beforeDirty);
+        assertEquals(afterDirty, l.afterDirty);
+        assertEquals(beforeDelete, l.beforeDelete);
+        assertEquals(afterDelete, l.afterDelete);
+    }
+}

Propchange: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/callbacks/TestMultiEmEntityListeners.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/validation/TestValidationMode.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/validation/TestValidationMode.java?rev=1307075&r1=1307074&r2=1307075&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/validation/TestValidationMode.java (original)
+++ openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/validation/TestValidationMode.java Thu Mar 29 19:43:04 2012
@@ -19,8 +19,11 @@ import java.util.Map;
 import javax.persistence.ValidationMode;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
-import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.event.LifecycleEvent;
+import org.apache.openjpa.event.PersistListener;
+import org.apache.openjpa.event.StoreListener;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 import org.apache.openjpa.persistence.OpenJPAPersistence;
 import org.apache.openjpa.persistence.PersistenceException;
 import org.apache.openjpa.persistence.query.SimpleEntity;
@@ -246,6 +249,92 @@ public class TestValidationMode extends 
         }
     }
 
+    /**
+     * Scenario being tested:
+     *   8) Life cycle event should be entity manager (Broker) specific.
+     */
+    public void testUniqueLifecycleManager() {
+        getLog().trace("testUniqueLifecycleManager() - Life cycle event tests");
+        // create our EMF
+        Map<String,String> prop = new HashMap<String,String>();
+        prop.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
+//        prop.put("openjpa.Compatibility", "SingletonLifecycleEventManager=true");
+
+        OpenJPAEntityManagerFactorySPI emf = (OpenJPAEntityManagerFactorySPI)
+            OpenJPAPersistence.createEntityManagerFactory(
+                "simple",
+                "org/apache/openjpa/persistence/validation/persistence.xml",
+                prop);
+        assertNotNull(emf);
+        try {
+            final OpenJPAEntityManagerSPI em = emf.createEntityManager();
+            final OpenJPAEntityManagerSPI em2 = emf.createEntityManager();
+            UniqueLifecycleListener l1 = new UniqueLifecycleListener();
+            UniqueLifecycleListener l2 = new UniqueLifecycleListener();
+            em.addLifecycleListener(l1, (Class<?>[])null);
+            em2.addLifecycleListener(l2, (Class<?>[])null);
+
+            l1.assertCounts(0, 0, 0, 0);
+            l2.assertCounts(0, 0, 0, 0);
+
+            em.getTransaction().begin();
+            SimpleEntity e1 = new SimpleEntity();
+            em.persist(e1);
+            l1.assertCounts(1, 1, 0, 0);
+            l2.assertCounts(0, 0, 0, 0);
+
+            em2.getTransaction().begin();
+            SimpleEntity e2 = new SimpleEntity();
+            em2.persist(e2);
+            l1.assertCounts(1, 1, 0, 0);
+            l2.assertCounts(1, 1, 0, 0);
+
+            em2.getTransaction().commit();
+            l1.assertCounts(1, 1, 0, 0);
+            l2.assertCounts(1, 1, 1, 1);
+
+            em.getTransaction().commit();
+            l1.assertCounts(1, 1, 1, 1);
+            l2.assertCounts(1, 1, 1, 1);
+        } finally {
+            cleanup(emf);
+        }
+    }
+
+    class UniqueLifecycleListener implements PersistListener, StoreListener {
+
+        public int beforePersistCount;
+        public int afterPersistCount;
+        public int beforeStoreCount;
+        public int afterStoreCount;
+
+        @Override
+        public void beforePersist(LifecycleEvent event) {
+            beforePersistCount++;
+        }
+
+        @Override
+        public void afterPersist(LifecycleEvent event) {
+            afterPersistCount++;
+        }
+
+        @Override
+        public void beforeStore(LifecycleEvent event) {
+            beforeStoreCount++;
+        }
+
+        @Override
+        public void afterStore(LifecycleEvent event) {
+            afterStoreCount++; 
+        }
+
+        public void assertCounts(int beforePersist, int afterPersist, int beforeStore, int afterStore) {
+            assertEquals(beforePersist, beforePersistCount);
+            assertEquals(afterPersist, afterPersistCount);
+            assertEquals(beforeStore, beforeStoreCount);
+            assertEquals(afterStore, afterStoreCount);
+        }
+    }
     
     /**
      * Helper method to remove entities and close the emf an any open em's.

Modified: openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml?rev=1307075&r1=1307074&r2=1307075&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml (original)
+++ openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml Thu Mar 29 19:43:04 2012
@@ -426,7 +426,7 @@
                             <para> Regenerate the canonical metamodel classes</para>
                         </listitem>
                         <listitem>
-                            <para> Set the Compatibility property <literal>UseListAttributeForArrays</literal> to <literal>true</literal>in persistence.xml 
+                            <para> Set the Compatibility property <literal>UseListAttributeForArrays</literal> to <literal>true</literal> in persistence.xml 
                                 <programlisting> &lt;property name="openjpa.Compatibility" value="UseListAttributeForArrays=true"/&gt;</programlisting>
                             </para>
                         </listitem>

Modified: openjpa/branches/2.2.x/openjpa-project/src/doc/manual/ref_guide_conf.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-project/src/doc/manual/ref_guide_conf.xml?rev=1307075&r1=1307074&r2=1307075&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-project/src/doc/manual/ref_guide_conf.xml (original)
+++ openjpa/branches/2.2.x/openjpa-project/src/doc/manual/ref_guide_conf.xml Thu Mar 29 19:43:04 2012
@@ -1811,6 +1811,36 @@ long-running application where the initi
 memory and speed optimization over time.
             </para>
         </section>
+        <section id="openjpa.DynamicEnhancementAgent">
+            <title>openjpa.DynamicEnhancementAgent</title>
+            <para> 
+                <emphasis role="bold">Property name: </emphasis>
+                <literal>openjpa.DynamicEnhancementAgent</literal>
+            </para>
+            <para>
+                 <emphasis role="bold">Configuration API: </emphasis>
+                 <ulink url="../javadoc/org/apache/openjpa/conf/OpenJPAConfiguration.html#getDynamicEnhancementAgent()">org.apache.openjpa.conf.OpenJPAConfiguration.getDynamicEnhancementAgent</ulink>
+            </para>
+            <para>
+                <emphasis role="bold">Resource adaptor config property:</emphasis>
+                DynamicEnhancementAgent
+            </para>
+            <para>
+                <emphasis role="bold">Default: </emphasis>
+                <literal>true</literal>
+                
+            </para>
+            <para>
+                <emphasis role="bold">Description:</emphasis>
+                The DynamicEnhancementAgent property controls whether or not
+                OpenJPA will attempt to dynamically load the PCEnhancer 
+                javaagent.
+            </para>
+            <para>
+                See the reference guide for more information 
+                <xref linkend="ref_guide_pc_enhance_dynamic"/>
+            </para>            
+        </section>
         <section id="openjpa.FetchBatchSize">
             <title>
                 openjpa.FetchBatchSize
@@ -3181,36 +3211,6 @@ serious problems.
                 <xref linkend="ref_guide_pc_enhance_unenhanced_types"/>
             </para>
         </section>
-        <section id="openjpa.DynamicEnhancementAgent">
-            <title>openjpa.DynamicEnhancementAgent</title>
-            <para> 
-                <emphasis role="bold">Property name: </emphasis>
-                <literal>openjpa.DynamicEnhancementAgent</literal>
-            </para>
-            <para>
-                 <emphasis role="bold">Configuration API: </emphasis>
-                 <ulink url="../javadoc/org/apache/openjpa/conf/OpenJPAConfiguration.html#getDynamicEnhancementAgent()">org.apache.openjpa.conf.OpenJPAConfiguration.getDynamicEnhancementAgent</ulink>
-            </para>
-            <para>
-                <emphasis role="bold">Resource adaptor config property:</emphasis>
-                DynamicEnhancementAgent
-            </para>
-            <para>
-                <emphasis role="bold">Default: </emphasis>
-                <literal>true</literal>
-                
-            </para>
-            <para>
-                <emphasis role="bold">Description:</emphasis>
-                The DynamicEnhancementAgent property controls whether or not
-                OpenJPA will attempt to dynamically load the PCEnhancer 
-                javaagent.
-            </para>
-            <para>
-                See the reference guide for more information 
-                <xref linkend="ref_guide_pc_enhance_dynamic"/>
-            </para>            
-        </section>
         <section id="openjpa.SavepointManager">
             <title>
                 openjpa.SavepointManager