synchronizing = true;
// This is an independent point of entry. We need to make sure the
// thread is associated with the right context class loader
Thread currentThread = Thread.currentThread();
CmpEntityBeanContext context = null;
try {
for (CmpEntityBeanContext instance : instances) {
// any one can mark the tx rollback at any time so check
// before continuing to the next store
if (TxUtils.isRollback(tx)) {
return;
}
context = instance;
context.getTxAssociation().invokeEjbStore(currentThread, context);
}
for (CmpEntityBeanContext instance : instances) {
// any one can mark the tx rollback at any time so check
// before continuing to the next store
if (TxUtils.isRollback(tx)) {
return;
}
context = instance;
context.getTxAssociation().synchronize(currentThread, tx, context);
}
} catch (Exception causeByException) {
// EJB 1.1 section 12.3.2 and EJB 2 section 18.3.3
// exception during store must log exception, mark tx for
// rollback and throw a TransactionRolledback[Local]Exception
// if using caller's transaction. All of this is handled by
// the AbstractTxInterceptor and LogInterceptor.
//
// All we need to do here is mark the transaction for rollback
// and rethrow the causeByException. The caller will handle logging
// and wraping with TransactionRolledback[Local]Exception.
try {
tx.setRollbackOnly();
} catch (Exception e) {
CmpLogger.ROOT_LOGGER.exceptionRollingBackTx(tx, e);
}
// Rethrow cause by exception
if (causeByException instanceof EJBException) {
throw (EJBException) causeByException;
}
throw CmpMessages.MESSAGES.failedToStoreEntity(((context == null || context.getPrimaryKeyUnchecked() == null) ? "<null>" : context.getPrimaryKeyUnchecked().toString()), causeByException);
} finally {
synchronizing = false;
}
}