You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2006/10/04 21:12:35 UTC

svn commit: r452981 - in /incubator/openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/event/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/ openjpa-lib/src/main/java/org...

Author: awhite
Date: Wed Oct  4 12:12:34 2006
New Revision: 452981

URL: http://svn.apache.org/viewvc?view=rev&rev=452981
Log:
Handle exceptions from transaction listeners appropriately. Allow user to
override default CallbackMode for both lifecycle and transaction listeners.


Modified:
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Broker.java
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
    incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
    incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
    incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java
    incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
    incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManager.java

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/event/LifecycleEventManager.java Wed Oct  4 12:12:34 2006
@@ -52,6 +52,21 @@
     private List _exceps = new LinkedList();
     private boolean _firing = false;
     private boolean _fail = false;
+    private boolean _failFast = false;
+
+    /**
+     * Whether to fail after first exception when firing events to listeners.
+     */
+    public boolean isFailFast() {
+        return _failFast;
+    }
+
+    /**
+     * Whether to fail after first exception when firing events to listeners.
+     */
+    public void setFailFast(boolean failFast) {
+        _failFast = failFast;
+    }
 
     /**
      * Register a lifecycle listener for the given classes. If the classes
@@ -207,22 +222,19 @@
         ClassMetaData meta, int type) {
         if (meta.getLifecycleMetaData().getIgnoreSystemListeners())
             return false;
-        boolean failFast = (meta.getRepository().getMetaDataFactory().
-            getDefaults().getCallbackMode() & CALLBACK_FAIL_FAST) != 0;
-        if (fireEvent(null, source, null, type, _listeners, true, failFast,
-            null) == Boolean.TRUE)
+        if (fireEvent(null, source, null, type, _listeners, true, null) 
+            == Boolean.TRUE)
             return true;
         ListenerList system = meta.getRepository().getSystemListeners();
         if (!system.isEmpty() && fireEvent(null, source, null, type, system,
-            true, failFast, null) == Boolean.TRUE)
+            true, null) == Boolean.TRUE)
             return true;
         if (_classListeners != null) {
             Class c = source == null ? meta.getDescribedType() :
                 source.getClass();
             do {
                 if (fireEvent(null, source, null, type, (ListenerList)
-                    _classListeners.get(c), true, failFast, null)
-                    == Boolean.TRUE)
+                    _classListeners.get(c), true, null) == Boolean.TRUE)
                     return true;
                 c = c.getSuperclass();
             } while (c != null && c != Object.class);
@@ -250,21 +262,18 @@
             getDefaults();
 
         boolean callbacks = def.getCallbacksBeforeListeners(type);
-        boolean failFast = (def.getCallbackMode() & CALLBACK_FAIL_FAST) != 0;
-
         if (callbacks)
-            makeCallbacks(source, related, meta, type, failFast, exceptions);
+            makeCallbacks(source, related, meta, type, exceptions);
 
         LifecycleEvent ev = (LifecycleEvent) fireEvent(null, source, related,
-            type, _listeners, false, failFast, exceptions);
+            type, _listeners, false, exceptions);
 
         if (_classListeners != null) {
             Class c = source == null ? meta.getDescribedType() :
                 source.getClass();
             do {
                 ev = (LifecycleEvent) fireEvent(ev, source, related, type,
-                    (ListenerList) _classListeners.get(c), false, failFast,
-                    exceptions);
+                    (ListenerList) _classListeners.get(c), false, exceptions);
                 c = c.getSuperclass();
             } while (c != null && c != Object.class);
         }
@@ -272,12 +281,11 @@
         // make system listeners
         if (!meta.getLifecycleMetaData().getIgnoreSystemListeners()) {
             ListenerList system = meta.getRepository().getSystemListeners();
-            fireEvent(ev, source, related, type, system, false, failFast,
-                exceptions);
+            fireEvent(ev, source, related, type, system, false, exceptions);
         }
 
         if (!callbacks)
-            makeCallbacks(source, related, meta, type, failFast, exceptions);
+            makeCallbacks(source, related, meta, type, exceptions);
 
         // create return array before clearing exceptions
         Exception[] ret;
@@ -309,7 +317,7 @@
      * Make callbacks, recording any exceptions in the given collection.
      */
     private void makeCallbacks(Object source, Object related,
-        ClassMetaData meta, int type, boolean failFast, Collection exceptions) {
+        ClassMetaData meta, int type, Collection exceptions) {
         // make lifecycle callbacks
         LifecycleCallbacks[] callbacks = meta.getLifecycleMetaData().
             getCallbacks(type);
@@ -318,7 +326,7 @@
                 callbacks[i].makeCallback(source, related, type);
             } catch (Exception e) {
                 exceptions.add(e);
-                if (failFast)
+                if (_failFast)
                     _fail = true;
             }
         }
@@ -329,8 +337,7 @@
      * listeners. The event may have already been constructed.
      */
     private Object fireEvent(LifecycleEvent ev, Object source, Object rel,
-        int type, ListenerList listeners, boolean mock, boolean failFast,
-        List exceptions) {
+        int type, ListenerList listeners, boolean mock, List exceptions) {
         if (listeners == null || !listeners.hasListeners(type))
             return null;
 
@@ -471,7 +478,7 @@
             }
             catch (Exception e) {
                 exceptions.add(e);
-                if (failFast)
+                if (_failFast)
                     _fail = true;
             }
         }

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Broker.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Broker.java?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Broker.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Broker.java Wed Oct  4 12:12:34 2006
@@ -21,6 +21,7 @@
 import javax.transaction.Synchronization;
 
 import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.event.CallbackModes;
 import org.apache.openjpa.event.LifecycleEventManager;
 import org.apache.openjpa.lib.util.Closeable;
 import org.apache.openjpa.meta.ClassMetaData;
@@ -40,7 +41,7 @@
     extends Synchronization, Connection, LocalTransaction,
     javax.resource.spi.LocalTransaction, Closeable, StoreContext,
     ConnectionRetainModes, DetachState, LockLevels,
-    RestoreState, AutoClear, AutoDetach {
+    RestoreState, AutoClear, AutoDetach, CallbackModes {
 
     /**
      * Set the broker's behavior for implicit actions such as flushing,
@@ -241,6 +242,18 @@
     public void removeTransactionListener(Object listener);
 
     /**
+     * The callback mode for handling exceptions from transaction event
+     * listeners.
+     */
+    public int getTransactionListenerCallbackMode();
+
+    /**
+     * The callback mode for handling exceptions from transaction event
+     * listeners.
+     */
+    public void setTransactionListenerCallbackMode(int mode);
+
+    /**
      * Register a listener for lifecycle-related events on the specified
      * classes. If the classes are null, all events will be propagated to
      * the listener.
@@ -260,6 +273,16 @@
      * Return the lifecycle event manager associated with the broker.
      */
     public LifecycleEventManager getLifecycleEventManager();
+
+    /**
+     * The callback mode for handling exceptions from lifecycle event listeners.
+     */
+    public int getLifecycleListenerCallbackMode();
+
+    /**
+     * The callback mode for handling exceptions from lifecycle event listeners.
+     */
+    public void setLifecycleListenerCallbackMode(int mode);
 
     /**
      * Begin a transaction.

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Wed Oct  4 12:12:34 2006
@@ -212,7 +212,6 @@
     private int _autoDetach = 0;
     private int _detachState = DETACH_LOADED;
     private boolean _detachedNew = true;
-    private int _callbackMode = CallbackModes.CALLBACK_IGNORE;
     private boolean _orderDirty = false;
 
     // status
@@ -221,7 +220,9 @@
 
     // event managers
     private TransactionEventManager _transEventManager = null;
+    private int _transCallbackMode = 0;
     private LifecycleEventManager _lifeEventManager = null;
+    private int _lifeCallbackMode = 0;
 
     /**
      * Set the persistence manager's authentication. This is the first
@@ -251,13 +252,10 @@
         DelegatingStoreManager sm, boolean managed, int connMode) {
         _conf = factory.getConfiguration();
         _compat = _conf.getCompatibilityInstance();
-
         _factory = factory;
         _log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
         _cache = new ManagedCache(newManagedObjectCache());
-        _lifeEventManager = new LifecycleEventManager();
-        _callbackMode = _conf.getMetaDataRepositoryInstance().
-            getMetaDataFactory(). getDefaults().getCallbackMode();
+        _operating = MapBackedSet.decorate(new IdentityMap());
         _connRetainMode = connMode;
         _managed = managed;
         if (managed)
@@ -265,9 +263,15 @@
         else
             _runtime = new LocalManagedRuntime(this);
 
+        _lifeEventManager = new LifecycleEventManager();
+        _transEventManager = new TransactionEventManager();
+        int cmode = _conf.getMetaDataRepositoryInstance().
+            getMetaDataFactory().getDefaults().getCallbackMode();
+        setLifecycleListenerCallbackMode(cmode);
+        setTransactionListenerCallbackMode(cmode);
+
         // setup default options
         _factory.configureBroker(this);
-        _operating = MapBackedSet.decorate(new IdentityMap());
 
         // make sure to do this after configuring broker so that store manager
         // can look to broker configuration; we set both store and lock managers
@@ -624,6 +628,20 @@
         }
     }
 
+    public int getLifecycleListenerCallbackMode() {
+        return _lifeCallbackMode;
+    }
+
+    public void setLifecycleListenerCallbackMode(int mode) {
+        beginOperation(false);
+        try {
+            _lifeCallbackMode = mode;
+            _lifeEventManager.setFailFast((mode & CALLBACK_FAIL_FAST) != 0);
+        } finally {
+            endOperation();
+        }
+    }
+
     /**
      * Give state managers access to the lifecycle event manager.
      */
@@ -632,41 +650,39 @@
     }
 
     /**
-     * Fire lifecycle events, handling any exceptions appropriately.
+     * Fire given lifecycle event, handling any exceptions appropriately.
      *
-     * @return whether events are being processed at this time.
+     * @return whether events are being processed at this time
      */
     boolean fireLifecycleEvent(Object src, Object related, ClassMetaData meta,
         int eventType) {
-        if (_lifeEventManager == null) // uninitialized
+        if (_lifeEventManager == null)
             return false;
+        handleCallbackExceptions(_lifeEventManager.fireEvent(src, related, 
+            meta, eventType), _lifeCallbackMode);
+        return true;
+    }
 
-        Exception[] exceps = _lifeEventManager.fireEvent(src, related, meta,
-            eventType);
-        if (exceps.length == 0
-            || (_callbackMode & CallbackModes.CALLBACK_IGNORE) != 0)
-            return true;
+    /**
+     * Take actions on callback exceptions depending on callback mode.
+     */
+    private void handleCallbackExceptions(Exception[] exceps, int mode) {
+        if (exceps.length == 0 || (mode & CALLBACK_IGNORE) != 0)
+            return;
 
-        OpenJPAException ke = new CallbackException
-            (_loc.get("callback-err", meta)).
+        OpenJPAException ke = new CallbackException(_loc.get("callback-err")).
             setNestedThrowables(exceps).setFatal(true);
-        if ((_callbackMode & CallbackModes.CALLBACK_ROLLBACK) != 0
-            && (_flags & FLAG_ACTIVE) != 0)
+        if ((mode & CALLBACK_ROLLBACK) != 0 && (_flags & FLAG_ACTIVE) != 0)
             setRollbackOnlyInternal();
-        if ((_callbackMode & CallbackModes.CALLBACK_LOG) != 0
-            && _log.isWarnEnabled())
+        if ((mode & CALLBACK_LOG) != 0 && _log.isWarnEnabled())
             _log.warn(ke);
-        if ((_callbackMode & CallbackModes.CALLBACK_RETHROW) != 0)
+        if ((mode & CALLBACK_RETHROW) != 0)
             throw ke;
-        return true;
     }
 
     public void addTransactionListener(Object tl) {
         beginOperation(false);
         try {
-            if (_transEventManager == null)
-                _transEventManager = new TransactionEventManager();
-
             _transEventManager.addListener(tl);
             if (tl instanceof RemoteCommitEventManager)
                 _flags |= FLAG_REMOTE_LISTENER;
@@ -678,8 +694,7 @@
     public void removeTransactionListener(Object tl) {
         beginOperation(false);
         try {
-            if (_transEventManager != null
-                && _transEventManager.removeListener(tl)
+            if (_transEventManager.removeListener(tl)
                 && (tl instanceof RemoteCommitEventManager))
                 _flags &= ~FLAG_REMOTE_LISTENER;
         } finally {
@@ -687,6 +702,31 @@
         }
     }
 
+    public int getTransactionListenerCallbackMode() {
+        return _transCallbackMode;
+    }
+
+    public void setTransactionListenerCallbackMode(int mode) {
+        beginOperation(false);
+        try {
+            _transCallbackMode = mode;
+            _transEventManager.setFailFast((mode & CALLBACK_FAIL_FAST) != 0);
+        } finally {
+            endOperation();
+        }
+    }
+
+    /**
+     * Fire given transaction event, handling any exceptions appropriately.
+     *
+     * @return whether events are being processed at this time
+     */
+    private void fireTransactionEvent(TransactionEvent trans) {
+        if (_transEventManager != null)
+            handleCallbackExceptions(_transEventManager.fireEvent(trans),
+                _transCallbackMode);
+    }
+
     ///////////
     // Lookups
     ///////////
@@ -1151,9 +1191,8 @@
             }
             _lm.beginTransaction();
 
-            if (_transEventManager != null
-                && _transEventManager.hasBeginListeners())
-                _transEventManager.fireEvent(new TransactionEvent(this,
+            if (_transEventManager.hasBeginListeners())
+                fireTransactionEvent(new TransactionEvent(this,
                     TransactionEvent.AFTER_BEGIN, null, null, null, null));
         } catch (OpenJPAException ke) {
             // if we already started the transaction, don't let it commit
@@ -1755,9 +1794,8 @@
             _flags &= ~FLAG_FLUSHED;
             _flags &= ~FLAG_TRANS_ENDING;
 
-            if (_transEventManager != null 
-                && _transEventManager.hasEndListeners()) {
-                _transEventManager.fireEvent(new TransactionEvent(this,
+            if (_transEventManager.hasEndListeners()) {
+                fireTransactionEvent(new TransactionEvent(this,
                     status == Status.STATUS_COMMITTED
                         ? TransactionEvent.AFTER_COMMIT_COMPLETE
                         : TransactionEvent.AFTER_ROLLBACK_COMPLETE,
@@ -1804,8 +1842,7 @@
         // special case the remote commit listener used by the datacache cause
         // we know it doesn't require the commit event when nothing changes
         boolean flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
-        boolean listeners = _transEventManager != null
-            && (_transEventManager.hasFlushListeners()
+        boolean listeners = (_transEventManager.hasFlushListeners()
             || _transEventManager.hasEndListeners())
             && ((_flags & FLAG_REMOTE_LISTENER) == 0
             || _transEventManager.getListeners().size() > 1);
@@ -1840,26 +1877,25 @@
                 if ((_flags & FLAG_STORE_ACTIVE) == 0)
                     beginStoreManagerTransaction(false);
 
-                if (_transEventManager != null
-                    && (_transEventManager.hasFlushListeners()
+                if ((_transEventManager.hasFlushListeners()
                     || _transEventManager.hasEndListeners())
                     && (flush || reason == FLUSH_COMMIT)) {
                     // fire events
                     mobjs = new ManagedObjectCollection(transactional);
                     if (reason == FLUSH_COMMIT
                         && _transEventManager.hasEndListeners()) {
-                        _transEventManager.fireEvent(new TransactionEvent
-                            (this, TransactionEvent.BEFORE_COMMIT, mobjs,
-                                _persistedClss, _updatedClss, _deletedClss));
+                        fireTransactionEvent(new TransactionEvent(this, 
+                            TransactionEvent.BEFORE_COMMIT, mobjs,
+                            _persistedClss, _updatedClss, _deletedClss));
 
                         flushAdditions(transactional, reason);
                         flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
                     }
 
                     if (flush && _transEventManager.hasFlushListeners()) {
-                        _transEventManager.fireEvent(new TransactionEvent
-                            (this, TransactionEvent.BEFORE_FLUSH, mobjs,
-                                _persistedClss, _updatedClss, _deletedClss));
+                        fireTransactionEvent(new TransactionEvent(this, 
+                            TransactionEvent.BEFORE_FLUSH, mobjs,
+                            _persistedClss, _updatedClss, _deletedClss));
                         flushAdditions(transactional, reason);
                     }
                 }
@@ -1922,9 +1958,8 @@
         throwNestedExceptions(exceps, true);
 
         if (flush && reason != FLUSH_ROLLBACK && reason != FLUSH_LOGICAL
-            && _transEventManager != null
             && _transEventManager.hasFlushListeners()) {
-            _transEventManager.fireEvent(new TransactionEvent(this,
+            fireTransactionEvent(new TransactionEvent(this,
                 TransactionEvent.AFTER_FLUSH, mobjs, _persistedClss,
                 _updatedClss, _deletedClss));
         }
@@ -2064,13 +2099,12 @@
 
         // fire after rollback/commit event
         Collection mobjs = null;
-        if (_transEventManager != null && _transEventManager.hasEndListeners())
-        {
+        if (_transEventManager.hasEndListeners()) {
             mobjs = new ManagedObjectCollection(transStates);
             int eventType = (rollback) ? TransactionEvent.AFTER_ROLLBACK
                 : TransactionEvent.AFTER_COMMIT;
-            _transEventManager.fireEvent(new TransactionEvent(this, eventType,
-                mobjs, _persistedClss, _updatedClss, _deletedClss));
+            fireTransactionEvent(new TransactionEvent(this, eventType, mobjs, 
+                _persistedClss, _updatedClss, _deletedClss));
         }
 
         // null transactional caches now so that all the removeFromTransaction
@@ -2130,10 +2164,9 @@
         _savepointCache = null;
 
         // fire after state change event
-        if (_transEventManager != null && _transEventManager.hasEndListeners())
-            _transEventManager.fireEvent(new TransactionEvent(this,
-                TransactionEvent.AFTER_STATE_TRANSITIONS, mobjs, null, null,
-                null));
+        if (_transEventManager.hasEndListeners())
+            fireTransactionEvent(new TransactionEvent(this, TransactionEvent.
+                AFTER_STATE_TRANSITIONS, mobjs, null, null, null));
 
         // now clear trans cache; keep cleared version rather than
         // null to avoid having to re-create the set later; more efficient

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java Wed Oct  4 12:12:34 2006
@@ -794,6 +794,22 @@
         }
     }
 
+    public int getTransactionListenerCallbackMode() {
+        try {
+            return _broker.getTransactionListenerCallbackMode();
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+    }
+
+    public void setTransactionListenerCallbackMode(int mode) {
+        try {
+            _broker.setTransactionListenerCallbackMode(mode);
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+    }
+
     public void addLifecycleListener(Object listener, Class[] classes) {
         try {
             _broker.addLifecycleListener(listener, classes);
@@ -805,6 +821,22 @@
     public void removeLifecycleListener(Object listener) {
         try {
             _broker.removeLifecycleListener(listener);
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+    }
+
+    public int getLifecycleListenerCallbackMode() {
+        try {
+            return _broker.getLifecycleListenerCallbackMode();
+        } catch (RuntimeException re) {
+            throw translate(re);
+        }
+    }
+
+    public void setLifecycleListenerCallbackMode(int mode) {
+        try {
+            _broker.setLifecycleListenerCallbackMode(mode);
         } catch (RuntimeException re) {
             throw translate(re);
         }

Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties Wed Oct  4 12:12:34 2006
@@ -320,7 +320,8 @@
 savepoint-flush-not-supported: The configured SavepointManager does not \
 	support incremental flushing when a savepoint has been set.  You must \
 	release your savepoints before flushing.
-callback-err: An error occured processing callbacks for instance of type "{0}".
+callback-err: Errors occured processing listener callbacks.  See the nested \
+    exceptions for details.
 bad-agg-listener-hint: Query hint value "{0}" ({1}) cannot be converted into \
 	an aggregate listener.
 bad-filter-listener-hint: Query hint value "{0}" ({1}) cannot be converted \

Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/AbstractConcurrentEventManager.java Wed Oct  4 12:12:34 2006
@@ -37,6 +37,7 @@
     private static Exception[] EMPTY_EXCEPTIONS = new Exception[0];
 
     private final Collection _listeners;
+    private boolean _failFast = false;
 
     /**
      * Default constructor.
@@ -46,6 +47,20 @@
     }
 
     /**
+     * Whether to fail after the first exception thrown by any listener.
+     */
+    public boolean isFailFast() {
+        return _failFast;
+    }
+
+    /**
+     * Whether to fail after the first exception thrown by any listener.
+     */
+    public void setFailFast(boolean failFast) {
+        _failFast = failFast;
+    }
+
+    /**
      * Register an event listener.
      */
     public void addListener(Object listener) {
@@ -93,6 +108,8 @@
             try {
                 fireEvent(event, itr.next());
             } catch (Exception e) {
+                if (_failFast)
+                    return new Exception[] { e };
                 if (exceptions == null)
                     exceptions = new LinkedList();
                 exceptions.add(e);

Modified: incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerImpl.java Wed Oct  4 12:12:34 2006
@@ -283,12 +283,28 @@
         _broker.removeTransactionListener(listener);
     }
 
+    public int getTransactionListenerCallbackMode() {
+        return _broker.getTransactionListenerCallbackMode();
+    }
+
+    public void setTransactionListenerCallbackMode(int mode) {
+        _broker.setTransactionListenerCallbackMode(mode);
+    }
+
     public void addLifecycleListener(Object listener, Class... classes) {
         _broker.addLifecycleListener(listener, classes);
     }
 
     public void removeLifecycleListener(Object listener) {
         _broker.removeLifecycleListener(listener);
+    }
+
+    public int getLifecycleListenerCallbackMode() {
+        return _broker.getLifecycleListenerCallbackMode();
+    }
+
+    public void setLifecycleListenerCallbackMode(int mode) {
+        _broker.setLifecycleListenerCallbackMode(mode);
     }
 
     @SuppressWarnings("unchecked")

Modified: incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManager.java?view=diff&rev=452981&r1=452980&r2=452981
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManager.java (original)
+++ incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/OpenJPAEntityManager.java Wed Oct  4 12:12:34 2006
@@ -23,6 +23,7 @@
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.ee.ManagedRuntime;
+import org.apache.openjpa.event.CallbackModes;
 import org.apache.openjpa.kernel.AutoClear;
 import org.apache.openjpa.kernel.AutoDetach;
 import org.apache.openjpa.kernel.ConnectionRetainModes;
@@ -41,7 +42,7 @@
     extends EntityManager, EntityTransaction, javax.resource.cci.Connection,
     javax.resource.cci.LocalTransaction, javax.resource.spi.LocalTransaction,
     Closeable, ConnectionRetainModes, DetachState, RestoreState, AutoDetach,
-    AutoClear {
+    AutoClear, CallbackModes {
 
     /**
      * Return the factory that produced this entity manager.
@@ -301,6 +302,18 @@
     public void removeTransactionListener(Object listener);
 
     /**
+     * The {@link CallbackModes} flags for handling transaction listener
+     * exceptions.
+     */
+    public int getTransactionListenerCallbackMode();
+
+    /**
+     * The {@link CallbackModes} flags for handling transaction listener
+     * exceptions.
+     */
+    public void setTransactionListenerCallbackMode(int callbackMode);
+
+    /**
      * Register a listener for lifecycle-related events on the specified
      * classes. If the classes are null, all events will be propagated to
      * the listener.
@@ -311,6 +324,18 @@
      * Remove a listener for lifecycle-related events.
      */
     public void removeLifecycleListener(Object listener);
+
+    /**
+     * The {@link CallbackModes} flags for handling lifecycle listener
+     * exceptions.
+     */
+    public int getLifecycleListenerCallbackMode();
+
+    /**
+     * The {@link CallbackModes} flags for handling lifecycle listener
+     * exceptions.
+     */
+    public void setLifecycleListenerCallbackMode(int callbackMode);
 
     ///////////
     // Lookups