mirror of https://github.com/apache/openjpa.git
Handle exceptions from transaction listeners appropriately. Allow user to
override default CallbackMode for both lifecycle and transaction listeners. git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@452981 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
88acae75c1
commit
8785be46e7
|
@ -52,6 +52,21 @@ public class LifecycleEventManager
|
||||||
private List _exceps = new LinkedList();
|
private List _exceps = new LinkedList();
|
||||||
private boolean _firing = false;
|
private boolean _firing = false;
|
||||||
private boolean _fail = 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
|
* Register a lifecycle listener for the given classes. If the classes
|
||||||
|
@ -207,22 +222,19 @@ public class LifecycleEventManager
|
||||||
ClassMetaData meta, int type) {
|
ClassMetaData meta, int type) {
|
||||||
if (meta.getLifecycleMetaData().getIgnoreSystemListeners())
|
if (meta.getLifecycleMetaData().getIgnoreSystemListeners())
|
||||||
return false;
|
return false;
|
||||||
boolean failFast = (meta.getRepository().getMetaDataFactory().
|
if (fireEvent(null, source, null, type, _listeners, true, null)
|
||||||
getDefaults().getCallbackMode() & CALLBACK_FAIL_FAST) != 0;
|
== Boolean.TRUE)
|
||||||
if (fireEvent(null, source, null, type, _listeners, true, failFast,
|
|
||||||
null) == Boolean.TRUE)
|
|
||||||
return true;
|
return true;
|
||||||
ListenerList system = meta.getRepository().getSystemListeners();
|
ListenerList system = meta.getRepository().getSystemListeners();
|
||||||
if (!system.isEmpty() && fireEvent(null, source, null, type, system,
|
if (!system.isEmpty() && fireEvent(null, source, null, type, system,
|
||||||
true, failFast, null) == Boolean.TRUE)
|
true, null) == Boolean.TRUE)
|
||||||
return true;
|
return true;
|
||||||
if (_classListeners != null) {
|
if (_classListeners != null) {
|
||||||
Class c = source == null ? meta.getDescribedType() :
|
Class c = source == null ? meta.getDescribedType() :
|
||||||
source.getClass();
|
source.getClass();
|
||||||
do {
|
do {
|
||||||
if (fireEvent(null, source, null, type, (ListenerList)
|
if (fireEvent(null, source, null, type, (ListenerList)
|
||||||
_classListeners.get(c), true, failFast, null)
|
_classListeners.get(c), true, null) == Boolean.TRUE)
|
||||||
== Boolean.TRUE)
|
|
||||||
return true;
|
return true;
|
||||||
c = c.getSuperclass();
|
c = c.getSuperclass();
|
||||||
} while (c != null && c != Object.class);
|
} while (c != null && c != Object.class);
|
||||||
|
@ -250,21 +262,18 @@ public class LifecycleEventManager
|
||||||
getDefaults();
|
getDefaults();
|
||||||
|
|
||||||
boolean callbacks = def.getCallbacksBeforeListeners(type);
|
boolean callbacks = def.getCallbacksBeforeListeners(type);
|
||||||
boolean failFast = (def.getCallbackMode() & CALLBACK_FAIL_FAST) != 0;
|
|
||||||
|
|
||||||
if (callbacks)
|
if (callbacks)
|
||||||
makeCallbacks(source, related, meta, type, failFast, exceptions);
|
makeCallbacks(source, related, meta, type, exceptions);
|
||||||
|
|
||||||
LifecycleEvent ev = (LifecycleEvent) fireEvent(null, source, related,
|
LifecycleEvent ev = (LifecycleEvent) fireEvent(null, source, related,
|
||||||
type, _listeners, false, failFast, exceptions);
|
type, _listeners, false, exceptions);
|
||||||
|
|
||||||
if (_classListeners != null) {
|
if (_classListeners != null) {
|
||||||
Class c = source == null ? meta.getDescribedType() :
|
Class c = source == null ? meta.getDescribedType() :
|
||||||
source.getClass();
|
source.getClass();
|
||||||
do {
|
do {
|
||||||
ev = (LifecycleEvent) fireEvent(ev, source, related, type,
|
ev = (LifecycleEvent) fireEvent(ev, source, related, type,
|
||||||
(ListenerList) _classListeners.get(c), false, failFast,
|
(ListenerList) _classListeners.get(c), false, exceptions);
|
||||||
exceptions);
|
|
||||||
c = c.getSuperclass();
|
c = c.getSuperclass();
|
||||||
} while (c != null && c != Object.class);
|
} while (c != null && c != Object.class);
|
||||||
}
|
}
|
||||||
|
@ -272,12 +281,11 @@ public class LifecycleEventManager
|
||||||
// make system listeners
|
// make system listeners
|
||||||
if (!meta.getLifecycleMetaData().getIgnoreSystemListeners()) {
|
if (!meta.getLifecycleMetaData().getIgnoreSystemListeners()) {
|
||||||
ListenerList system = meta.getRepository().getSystemListeners();
|
ListenerList system = meta.getRepository().getSystemListeners();
|
||||||
fireEvent(ev, source, related, type, system, false, failFast,
|
fireEvent(ev, source, related, type, system, false, exceptions);
|
||||||
exceptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!callbacks)
|
if (!callbacks)
|
||||||
makeCallbacks(source, related, meta, type, failFast, exceptions);
|
makeCallbacks(source, related, meta, type, exceptions);
|
||||||
|
|
||||||
// create return array before clearing exceptions
|
// create return array before clearing exceptions
|
||||||
Exception[] ret;
|
Exception[] ret;
|
||||||
|
@ -309,7 +317,7 @@ public class LifecycleEventManager
|
||||||
* Make callbacks, recording any exceptions in the given collection.
|
* Make callbacks, recording any exceptions in the given collection.
|
||||||
*/
|
*/
|
||||||
private void makeCallbacks(Object source, Object related,
|
private void makeCallbacks(Object source, Object related,
|
||||||
ClassMetaData meta, int type, boolean failFast, Collection exceptions) {
|
ClassMetaData meta, int type, Collection exceptions) {
|
||||||
// make lifecycle callbacks
|
// make lifecycle callbacks
|
||||||
LifecycleCallbacks[] callbacks = meta.getLifecycleMetaData().
|
LifecycleCallbacks[] callbacks = meta.getLifecycleMetaData().
|
||||||
getCallbacks(type);
|
getCallbacks(type);
|
||||||
|
@ -318,7 +326,7 @@ public class LifecycleEventManager
|
||||||
callbacks[i].makeCallback(source, related, type);
|
callbacks[i].makeCallback(source, related, type);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exceptions.add(e);
|
exceptions.add(e);
|
||||||
if (failFast)
|
if (_failFast)
|
||||||
_fail = true;
|
_fail = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,8 +337,7 @@ public class LifecycleEventManager
|
||||||
* listeners. The event may have already been constructed.
|
* listeners. The event may have already been constructed.
|
||||||
*/
|
*/
|
||||||
private Object fireEvent(LifecycleEvent ev, Object source, Object rel,
|
private Object fireEvent(LifecycleEvent ev, Object source, Object rel,
|
||||||
int type, ListenerList listeners, boolean mock, boolean failFast,
|
int type, ListenerList listeners, boolean mock, List exceptions) {
|
||||||
List exceptions) {
|
|
||||||
if (listeners == null || !listeners.hasListeners(type))
|
if (listeners == null || !listeners.hasListeners(type))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -471,7 +478,7 @@ public class LifecycleEventManager
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
exceptions.add(e);
|
exceptions.add(e);
|
||||||
if (failFast)
|
if (_failFast)
|
||||||
_fail = true;
|
_fail = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import javax.resource.cci.LocalTransaction;
|
||||||
import javax.transaction.Synchronization;
|
import javax.transaction.Synchronization;
|
||||||
|
|
||||||
import org.apache.openjpa.ee.ManagedRuntime;
|
import org.apache.openjpa.ee.ManagedRuntime;
|
||||||
|
import org.apache.openjpa.event.CallbackModes;
|
||||||
import org.apache.openjpa.event.LifecycleEventManager;
|
import org.apache.openjpa.event.LifecycleEventManager;
|
||||||
import org.apache.openjpa.lib.util.Closeable;
|
import org.apache.openjpa.lib.util.Closeable;
|
||||||
import org.apache.openjpa.meta.ClassMetaData;
|
import org.apache.openjpa.meta.ClassMetaData;
|
||||||
|
@ -40,7 +41,7 @@ public interface Broker
|
||||||
extends Synchronization, Connection, LocalTransaction,
|
extends Synchronization, Connection, LocalTransaction,
|
||||||
javax.resource.spi.LocalTransaction, Closeable, StoreContext,
|
javax.resource.spi.LocalTransaction, Closeable, StoreContext,
|
||||||
ConnectionRetainModes, DetachState, LockLevels,
|
ConnectionRetainModes, DetachState, LockLevels,
|
||||||
RestoreState, AutoClear, AutoDetach {
|
RestoreState, AutoClear, AutoDetach, CallbackModes {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the broker's behavior for implicit actions such as flushing,
|
* Set the broker's behavior for implicit actions such as flushing,
|
||||||
|
@ -240,6 +241,18 @@ public interface Broker
|
||||||
*/
|
*/
|
||||||
public void removeTransactionListener(Object listener);
|
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
|
* Register a listener for lifecycle-related events on the specified
|
||||||
* classes. If the classes are null, all events will be propagated to
|
* classes. If the classes are null, all events will be propagated to
|
||||||
|
@ -261,6 +274,16 @@ public interface Broker
|
||||||
*/
|
*/
|
||||||
public LifecycleEventManager getLifecycleEventManager();
|
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.
|
* Begin a transaction.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -212,7 +212,6 @@ public class BrokerImpl
|
||||||
private int _autoDetach = 0;
|
private int _autoDetach = 0;
|
||||||
private int _detachState = DETACH_LOADED;
|
private int _detachState = DETACH_LOADED;
|
||||||
private boolean _detachedNew = true;
|
private boolean _detachedNew = true;
|
||||||
private int _callbackMode = CallbackModes.CALLBACK_IGNORE;
|
|
||||||
private boolean _orderDirty = false;
|
private boolean _orderDirty = false;
|
||||||
|
|
||||||
// status
|
// status
|
||||||
|
@ -221,7 +220,9 @@ public class BrokerImpl
|
||||||
|
|
||||||
// event managers
|
// event managers
|
||||||
private TransactionEventManager _transEventManager = null;
|
private TransactionEventManager _transEventManager = null;
|
||||||
|
private int _transCallbackMode = 0;
|
||||||
private LifecycleEventManager _lifeEventManager = null;
|
private LifecycleEventManager _lifeEventManager = null;
|
||||||
|
private int _lifeCallbackMode = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the persistence manager's authentication. This is the first
|
* Set the persistence manager's authentication. This is the first
|
||||||
|
@ -251,13 +252,10 @@ public class BrokerImpl
|
||||||
DelegatingStoreManager sm, boolean managed, int connMode) {
|
DelegatingStoreManager sm, boolean managed, int connMode) {
|
||||||
_conf = factory.getConfiguration();
|
_conf = factory.getConfiguration();
|
||||||
_compat = _conf.getCompatibilityInstance();
|
_compat = _conf.getCompatibilityInstance();
|
||||||
|
|
||||||
_factory = factory;
|
_factory = factory;
|
||||||
_log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
|
_log = _conf.getLog(OpenJPAConfiguration.LOG_RUNTIME);
|
||||||
_cache = new ManagedCache(newManagedObjectCache());
|
_cache = new ManagedCache(newManagedObjectCache());
|
||||||
_lifeEventManager = new LifecycleEventManager();
|
_operating = MapBackedSet.decorate(new IdentityMap());
|
||||||
_callbackMode = _conf.getMetaDataRepositoryInstance().
|
|
||||||
getMetaDataFactory(). getDefaults().getCallbackMode();
|
|
||||||
_connRetainMode = connMode;
|
_connRetainMode = connMode;
|
||||||
_managed = managed;
|
_managed = managed;
|
||||||
if (managed)
|
if (managed)
|
||||||
|
@ -265,9 +263,15 @@ public class BrokerImpl
|
||||||
else
|
else
|
||||||
_runtime = new LocalManagedRuntime(this);
|
_runtime = new LocalManagedRuntime(this);
|
||||||
|
|
||||||
|
_lifeEventManager = new LifecycleEventManager();
|
||||||
|
_transEventManager = new TransactionEventManager();
|
||||||
|
int cmode = _conf.getMetaDataRepositoryInstance().
|
||||||
|
getMetaDataFactory().getDefaults().getCallbackMode();
|
||||||
|
setLifecycleListenerCallbackMode(cmode);
|
||||||
|
setTransactionListenerCallbackMode(cmode);
|
||||||
|
|
||||||
// setup default options
|
// setup default options
|
||||||
_factory.configureBroker(this);
|
_factory.configureBroker(this);
|
||||||
_operating = MapBackedSet.decorate(new IdentityMap());
|
|
||||||
|
|
||||||
// make sure to do this after configuring broker so that store manager
|
// make sure to do this after configuring broker so that store manager
|
||||||
// can look to broker configuration; we set both store and lock managers
|
// can look to broker configuration; we set both store and lock managers
|
||||||
|
@ -624,6 +628,20 @@ public class BrokerImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
* Give state managers access to the lifecycle event manager.
|
||||||
*/
|
*/
|
||||||
|
@ -632,41 +650,39 @@ public class BrokerImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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,
|
boolean fireLifecycleEvent(Object src, Object related, ClassMetaData meta,
|
||||||
int eventType) {
|
int eventType) {
|
||||||
if (_lifeEventManager == null) // uninitialized
|
if (_lifeEventManager == null)
|
||||||
return false;
|
return false;
|
||||||
|
handleCallbackExceptions(_lifeEventManager.fireEvent(src, related,
|
||||||
Exception[] exceps = _lifeEventManager.fireEvent(src, related, meta,
|
meta, eventType), _lifeCallbackMode);
|
||||||
eventType);
|
|
||||||
if (exceps.length == 0
|
|
||||||
|| (_callbackMode & CallbackModes.CALLBACK_IGNORE) != 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
OpenJPAException ke = new CallbackException
|
|
||||||
(_loc.get("callback-err", meta)).
|
|
||||||
setNestedThrowables(exceps).setFatal(true);
|
|
||||||
if ((_callbackMode & CallbackModes.CALLBACK_ROLLBACK) != 0
|
|
||||||
&& (_flags & FLAG_ACTIVE) != 0)
|
|
||||||
setRollbackOnlyInternal();
|
|
||||||
if ((_callbackMode & CallbackModes.CALLBACK_LOG) != 0
|
|
||||||
&& _log.isWarnEnabled())
|
|
||||||
_log.warn(ke);
|
|
||||||
if ((_callbackMode & CallbackModes.CALLBACK_RETHROW) != 0)
|
|
||||||
throw ke;
|
|
||||||
return true;
|
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")).
|
||||||
|
setNestedThrowables(exceps).setFatal(true);
|
||||||
|
if ((mode & CALLBACK_ROLLBACK) != 0 && (_flags & FLAG_ACTIVE) != 0)
|
||||||
|
setRollbackOnlyInternal();
|
||||||
|
if ((mode & CALLBACK_LOG) != 0 && _log.isWarnEnabled())
|
||||||
|
_log.warn(ke);
|
||||||
|
if ((mode & CALLBACK_RETHROW) != 0)
|
||||||
|
throw ke;
|
||||||
|
}
|
||||||
|
|
||||||
public void addTransactionListener(Object tl) {
|
public void addTransactionListener(Object tl) {
|
||||||
beginOperation(false);
|
beginOperation(false);
|
||||||
try {
|
try {
|
||||||
if (_transEventManager == null)
|
|
||||||
_transEventManager = new TransactionEventManager();
|
|
||||||
|
|
||||||
_transEventManager.addListener(tl);
|
_transEventManager.addListener(tl);
|
||||||
if (tl instanceof RemoteCommitEventManager)
|
if (tl instanceof RemoteCommitEventManager)
|
||||||
_flags |= FLAG_REMOTE_LISTENER;
|
_flags |= FLAG_REMOTE_LISTENER;
|
||||||
|
@ -678,8 +694,7 @@ public class BrokerImpl
|
||||||
public void removeTransactionListener(Object tl) {
|
public void removeTransactionListener(Object tl) {
|
||||||
beginOperation(false);
|
beginOperation(false);
|
||||||
try {
|
try {
|
||||||
if (_transEventManager != null
|
if (_transEventManager.removeListener(tl)
|
||||||
&& _transEventManager.removeListener(tl)
|
|
||||||
&& (tl instanceof RemoteCommitEventManager))
|
&& (tl instanceof RemoteCommitEventManager))
|
||||||
_flags &= ~FLAG_REMOTE_LISTENER;
|
_flags &= ~FLAG_REMOTE_LISTENER;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -687,6 +702,31 @@ public class BrokerImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// Lookups
|
||||||
///////////
|
///////////
|
||||||
|
@ -1151,9 +1191,8 @@ public class BrokerImpl
|
||||||
}
|
}
|
||||||
_lm.beginTransaction();
|
_lm.beginTransaction();
|
||||||
|
|
||||||
if (_transEventManager != null
|
if (_transEventManager.hasBeginListeners())
|
||||||
&& _transEventManager.hasBeginListeners())
|
fireTransactionEvent(new TransactionEvent(this,
|
||||||
_transEventManager.fireEvent(new TransactionEvent(this,
|
|
||||||
TransactionEvent.AFTER_BEGIN, null, null, null, null));
|
TransactionEvent.AFTER_BEGIN, null, null, null, null));
|
||||||
} catch (OpenJPAException ke) {
|
} catch (OpenJPAException ke) {
|
||||||
// if we already started the transaction, don't let it commit
|
// if we already started the transaction, don't let it commit
|
||||||
|
@ -1755,9 +1794,8 @@ public class BrokerImpl
|
||||||
_flags &= ~FLAG_FLUSHED;
|
_flags &= ~FLAG_FLUSHED;
|
||||||
_flags &= ~FLAG_TRANS_ENDING;
|
_flags &= ~FLAG_TRANS_ENDING;
|
||||||
|
|
||||||
if (_transEventManager != null
|
if (_transEventManager.hasEndListeners()) {
|
||||||
&& _transEventManager.hasEndListeners()) {
|
fireTransactionEvent(new TransactionEvent(this,
|
||||||
_transEventManager.fireEvent(new TransactionEvent(this,
|
|
||||||
status == Status.STATUS_COMMITTED
|
status == Status.STATUS_COMMITTED
|
||||||
? TransactionEvent.AFTER_COMMIT_COMPLETE
|
? TransactionEvent.AFTER_COMMIT_COMPLETE
|
||||||
: TransactionEvent.AFTER_ROLLBACK_COMPLETE,
|
: TransactionEvent.AFTER_ROLLBACK_COMPLETE,
|
||||||
|
@ -1804,8 +1842,7 @@ public class BrokerImpl
|
||||||
// special case the remote commit listener used by the datacache cause
|
// special case the remote commit listener used by the datacache cause
|
||||||
// we know it doesn't require the commit event when nothing changes
|
// we know it doesn't require the commit event when nothing changes
|
||||||
boolean flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
|
boolean flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
|
||||||
boolean listeners = _transEventManager != null
|
boolean listeners = (_transEventManager.hasFlushListeners()
|
||||||
&& (_transEventManager.hasFlushListeners()
|
|
||||||
|| _transEventManager.hasEndListeners())
|
|| _transEventManager.hasEndListeners())
|
||||||
&& ((_flags & FLAG_REMOTE_LISTENER) == 0
|
&& ((_flags & FLAG_REMOTE_LISTENER) == 0
|
||||||
|| _transEventManager.getListeners().size() > 1);
|
|| _transEventManager.getListeners().size() > 1);
|
||||||
|
@ -1840,26 +1877,25 @@ public class BrokerImpl
|
||||||
if ((_flags & FLAG_STORE_ACTIVE) == 0)
|
if ((_flags & FLAG_STORE_ACTIVE) == 0)
|
||||||
beginStoreManagerTransaction(false);
|
beginStoreManagerTransaction(false);
|
||||||
|
|
||||||
if (_transEventManager != null
|
if ((_transEventManager.hasFlushListeners()
|
||||||
&& (_transEventManager.hasFlushListeners()
|
|
||||||
|| _transEventManager.hasEndListeners())
|
|| _transEventManager.hasEndListeners())
|
||||||
&& (flush || reason == FLUSH_COMMIT)) {
|
&& (flush || reason == FLUSH_COMMIT)) {
|
||||||
// fire events
|
// fire events
|
||||||
mobjs = new ManagedObjectCollection(transactional);
|
mobjs = new ManagedObjectCollection(transactional);
|
||||||
if (reason == FLUSH_COMMIT
|
if (reason == FLUSH_COMMIT
|
||||||
&& _transEventManager.hasEndListeners()) {
|
&& _transEventManager.hasEndListeners()) {
|
||||||
_transEventManager.fireEvent(new TransactionEvent
|
fireTransactionEvent(new TransactionEvent(this,
|
||||||
(this, TransactionEvent.BEFORE_COMMIT, mobjs,
|
TransactionEvent.BEFORE_COMMIT, mobjs,
|
||||||
_persistedClss, _updatedClss, _deletedClss));
|
_persistedClss, _updatedClss, _deletedClss));
|
||||||
|
|
||||||
flushAdditions(transactional, reason);
|
flushAdditions(transactional, reason);
|
||||||
flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
|
flush = (_flags & FLAG_FLUSH_REQUIRED) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flush && _transEventManager.hasFlushListeners()) {
|
if (flush && _transEventManager.hasFlushListeners()) {
|
||||||
_transEventManager.fireEvent(new TransactionEvent
|
fireTransactionEvent(new TransactionEvent(this,
|
||||||
(this, TransactionEvent.BEFORE_FLUSH, mobjs,
|
TransactionEvent.BEFORE_FLUSH, mobjs,
|
||||||
_persistedClss, _updatedClss, _deletedClss));
|
_persistedClss, _updatedClss, _deletedClss));
|
||||||
flushAdditions(transactional, reason);
|
flushAdditions(transactional, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1922,9 +1958,8 @@ public class BrokerImpl
|
||||||
throwNestedExceptions(exceps, true);
|
throwNestedExceptions(exceps, true);
|
||||||
|
|
||||||
if (flush && reason != FLUSH_ROLLBACK && reason != FLUSH_LOGICAL
|
if (flush && reason != FLUSH_ROLLBACK && reason != FLUSH_LOGICAL
|
||||||
&& _transEventManager != null
|
|
||||||
&& _transEventManager.hasFlushListeners()) {
|
&& _transEventManager.hasFlushListeners()) {
|
||||||
_transEventManager.fireEvent(new TransactionEvent(this,
|
fireTransactionEvent(new TransactionEvent(this,
|
||||||
TransactionEvent.AFTER_FLUSH, mobjs, _persistedClss,
|
TransactionEvent.AFTER_FLUSH, mobjs, _persistedClss,
|
||||||
_updatedClss, _deletedClss));
|
_updatedClss, _deletedClss));
|
||||||
}
|
}
|
||||||
|
@ -2064,13 +2099,12 @@ public class BrokerImpl
|
||||||
|
|
||||||
// fire after rollback/commit event
|
// fire after rollback/commit event
|
||||||
Collection mobjs = null;
|
Collection mobjs = null;
|
||||||
if (_transEventManager != null && _transEventManager.hasEndListeners())
|
if (_transEventManager.hasEndListeners()) {
|
||||||
{
|
|
||||||
mobjs = new ManagedObjectCollection(transStates);
|
mobjs = new ManagedObjectCollection(transStates);
|
||||||
int eventType = (rollback) ? TransactionEvent.AFTER_ROLLBACK
|
int eventType = (rollback) ? TransactionEvent.AFTER_ROLLBACK
|
||||||
: TransactionEvent.AFTER_COMMIT;
|
: TransactionEvent.AFTER_COMMIT;
|
||||||
_transEventManager.fireEvent(new TransactionEvent(this, eventType,
|
fireTransactionEvent(new TransactionEvent(this, eventType, mobjs,
|
||||||
mobjs, _persistedClss, _updatedClss, _deletedClss));
|
_persistedClss, _updatedClss, _deletedClss));
|
||||||
}
|
}
|
||||||
|
|
||||||
// null transactional caches now so that all the removeFromTransaction
|
// null transactional caches now so that all the removeFromTransaction
|
||||||
|
@ -2130,10 +2164,9 @@ public class BrokerImpl
|
||||||
_savepointCache = null;
|
_savepointCache = null;
|
||||||
|
|
||||||
// fire after state change event
|
// fire after state change event
|
||||||
if (_transEventManager != null && _transEventManager.hasEndListeners())
|
if (_transEventManager.hasEndListeners())
|
||||||
_transEventManager.fireEvent(new TransactionEvent(this,
|
fireTransactionEvent(new TransactionEvent(this, TransactionEvent.
|
||||||
TransactionEvent.AFTER_STATE_TRANSITIONS, mobjs, null, null,
|
AFTER_STATE_TRANSITIONS, mobjs, null, null, null));
|
||||||
null));
|
|
||||||
|
|
||||||
// now clear trans cache; keep cleared version rather than
|
// now clear trans cache; keep cleared version rather than
|
||||||
// null to avoid having to re-create the set later; more efficient
|
// null to avoid having to re-create the set later; more efficient
|
||||||
|
|
|
@ -794,6 +794,22 @@ public class DelegatingBroker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
public void addLifecycleListener(Object listener, Class[] classes) {
|
||||||
try {
|
try {
|
||||||
_broker.addLifecycleListener(listener, classes);
|
_broker.addLifecycleListener(listener, classes);
|
||||||
|
@ -810,6 +826,22 @@ public class DelegatingBroker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public LifecycleEventManager getLifecycleEventManager() {
|
public LifecycleEventManager getLifecycleEventManager() {
|
||||||
try {
|
try {
|
||||||
return _broker.getLifecycleEventManager();
|
return _broker.getLifecycleEventManager();
|
||||||
|
|
|
@ -320,7 +320,8 @@ savepoint-init: This savepoint has already been initialized.
|
||||||
savepoint-flush-not-supported: The configured SavepointManager does not \
|
savepoint-flush-not-supported: The configured SavepointManager does not \
|
||||||
support incremental flushing when a savepoint has been set. You must \
|
support incremental flushing when a savepoint has been set. You must \
|
||||||
release your savepoints before flushing.
|
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 \
|
bad-agg-listener-hint: Query hint value "{0}" ({1}) cannot be converted into \
|
||||||
an aggregate listener.
|
an aggregate listener.
|
||||||
bad-filter-listener-hint: Query hint value "{0}" ({1}) cannot be converted \
|
bad-filter-listener-hint: Query hint value "{0}" ({1}) cannot be converted \
|
||||||
|
|
|
@ -37,6 +37,7 @@ public abstract class AbstractConcurrentEventManager implements EventManager {
|
||||||
private static Exception[] EMPTY_EXCEPTIONS = new Exception[0];
|
private static Exception[] EMPTY_EXCEPTIONS = new Exception[0];
|
||||||
|
|
||||||
private final Collection _listeners;
|
private final Collection _listeners;
|
||||||
|
private boolean _failFast = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
|
@ -45,6 +46,20 @@ public abstract class AbstractConcurrentEventManager implements EventManager {
|
||||||
_listeners = newListenerCollection();
|
_listeners = newListenerCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Register an event listener.
|
||||||
*/
|
*/
|
||||||
|
@ -93,6 +108,8 @@ public abstract class AbstractConcurrentEventManager implements EventManager {
|
||||||
try {
|
try {
|
||||||
fireEvent(event, itr.next());
|
fireEvent(event, itr.next());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
if (_failFast)
|
||||||
|
return new Exception[] { e };
|
||||||
if (exceptions == null)
|
if (exceptions == null)
|
||||||
exceptions = new LinkedList();
|
exceptions = new LinkedList();
|
||||||
exceptions.add(e);
|
exceptions.add(e);
|
||||||
|
|
|
@ -283,6 +283,14 @@ public class EntityManagerImpl
|
||||||
_broker.removeTransactionListener(listener);
|
_broker.removeTransactionListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getTransactionListenerCallbackMode() {
|
||||||
|
return _broker.getTransactionListenerCallbackMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionListenerCallbackMode(int mode) {
|
||||||
|
_broker.setTransactionListenerCallbackMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
public void addLifecycleListener(Object listener, Class... classes) {
|
public void addLifecycleListener(Object listener, Class... classes) {
|
||||||
_broker.addLifecycleListener(listener, classes);
|
_broker.addLifecycleListener(listener, classes);
|
||||||
}
|
}
|
||||||
|
@ -291,6 +299,14 @@ public class EntityManagerImpl
|
||||||
_broker.removeLifecycleListener(listener);
|
_broker.removeLifecycleListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLifecycleListenerCallbackMode() {
|
||||||
|
return _broker.getLifecycleListenerCallbackMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLifecycleListenerCallbackMode(int mode) {
|
||||||
|
_broker.setLifecycleListenerCallbackMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T getReference(Class<T> cls, Object oid) {
|
public <T> T getReference(Class<T> cls, Object oid) {
|
||||||
oid = _broker.newObjectId(cls, oid);
|
oid = _broker.newObjectId(cls, oid);
|
||||||
|
|
|
@ -23,6 +23,7 @@ import javax.persistence.Query;
|
||||||
|
|
||||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||||
import org.apache.openjpa.ee.ManagedRuntime;
|
import org.apache.openjpa.ee.ManagedRuntime;
|
||||||
|
import org.apache.openjpa.event.CallbackModes;
|
||||||
import org.apache.openjpa.kernel.AutoClear;
|
import org.apache.openjpa.kernel.AutoClear;
|
||||||
import org.apache.openjpa.kernel.AutoDetach;
|
import org.apache.openjpa.kernel.AutoDetach;
|
||||||
import org.apache.openjpa.kernel.ConnectionRetainModes;
|
import org.apache.openjpa.kernel.ConnectionRetainModes;
|
||||||
|
@ -41,7 +42,7 @@ public interface OpenJPAEntityManager
|
||||||
extends EntityManager, EntityTransaction, javax.resource.cci.Connection,
|
extends EntityManager, EntityTransaction, javax.resource.cci.Connection,
|
||||||
javax.resource.cci.LocalTransaction, javax.resource.spi.LocalTransaction,
|
javax.resource.cci.LocalTransaction, javax.resource.spi.LocalTransaction,
|
||||||
Closeable, ConnectionRetainModes, DetachState, RestoreState, AutoDetach,
|
Closeable, ConnectionRetainModes, DetachState, RestoreState, AutoDetach,
|
||||||
AutoClear {
|
AutoClear, CallbackModes {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the factory that produced this entity manager.
|
* Return the factory that produced this entity manager.
|
||||||
|
@ -300,6 +301,18 @@ public interface OpenJPAEntityManager
|
||||||
*/
|
*/
|
||||||
public void removeTransactionListener(Object listener);
|
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
|
* Register a listener for lifecycle-related events on the specified
|
||||||
* classes. If the classes are null, all events will be propagated to
|
* classes. If the classes are null, all events will be propagated to
|
||||||
|
@ -312,6 +325,18 @@ public interface OpenJPAEntityManager
|
||||||
*/
|
*/
|
||||||
public void removeLifecycleListener(Object listener);
|
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
|
// Lookups
|
||||||
///////////
|
///////////
|
||||||
|
|
Loading…
Reference in New Issue