Search in sources :

Example 6 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class EntityContainer method removeEJBObject.

protected void removeEJBObject(final Method callMethod, final Object[] args, final ThreadContext callContext, final InterfaceType type) throws OpenEJBException {
    callContext.setCurrentOperation(Operation.REMOVE);
    final BeanContext beanContext = callContext.getBeanContext();
    final TransactionPolicy txPolicy = createTransactionPolicy(beanContext.getTransactionType(callMethod, type), callContext);
    EntityBean bean = null;
    try {
        bean = instanceManager.obtainInstance(callContext);
        ejbLoad_If_No_Transaction(callContext, bean);
        bean.ejbRemove();
        didRemove(bean, callContext);
        instanceManager.poolInstance(callContext, bean, callContext.getPrimaryKey());
    } catch (final Throwable e) {
        handleException(txPolicy, e, callContext, bean);
    } finally {
        afterInvoke(txPolicy, callContext);
    }
}
Also used : BeanContext(org.apache.openejb.BeanContext) EntityBean(javax.ejb.EntityBean) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) EjbTransactionUtil.createTransactionPolicy(org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy)

Example 7 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class ManagedContainer method removeEJBObject.

protected Object removeEJBObject(final BeanContext beanContext, final Object primKey, final Class callInterface, final Method callMethod, Object[] args, final InterfaceType interfaceType) throws OpenEJBException {
    if (primKey == null) {
        throw new NullPointerException("primKey is null");
    }
    final ThreadContext callContext = new ThreadContext(beanContext, primKey);
    final ThreadContext oldCallContext = ThreadContext.enter(callContext);
    try {
        // Security check
        final boolean internalRemove = BeanContext.Removable.class == callMethod.getDeclaringClass();
        if (!internalRemove) {
            checkAuthorization(callMethod, interfaceType);
        }
        // If a bean managed transaction is active, the bean can not be removed
        if (interfaceType.isComponent()) {
            final Instance instance = checkedOutInstances.get(primKey);
            /**
                 * According to EJB 3.0 "4.4.4 Restrictions for Transactions" any remove methods
                 * from home or component interfaces must not be allowed if the bean instance is
                 * in a transaction.  Unfortunately, the Java EE 5 TCK has tests that ignore the
                 * restrictions in 4.4.4 and expect beans in transactions can be removed via their
                 * home or component interface.   The test to see if the bean instance implements
                 * javax.ejb.SessionBean is a workaround for passing the TCK while the tests in
                 * question can be challenged or the spec can be changed/updated.
                 */
            if (instance != null && instance.bean instanceof SessionBean) {
                throw new ApplicationException(new RemoveException("A stateful EJB enrolled in a transaction can not be removed"));
            }
        }
        // Start transaction
        final TransactionPolicy txPolicy = EjbTransactionUtil.createTransactionPolicy(callContext.getBeanContext().getTransactionType(callMethod, interfaceType), callContext);
        Object returnValue = null;
        boolean retain = false;
        Instance instance = null;
        Method runMethod = null;
        try {
            // Obtain instance
            instance = obtainInstance(primKey, callContext);
            // Resume previous Bean transaction if there was one
            if (txPolicy instanceof BeanTransactionPolicy) {
                // Resume previous Bean transaction if there was one
                final SuspendedTransaction suspendedTransaction = instance.getBeanTransaction();
                if (suspendedTransaction != null) {
                    instance.setBeanTransaction(null);
                    final BeanTransactionPolicy beanTxEnv = (BeanTransactionPolicy) txPolicy;
                    beanTxEnv.resumeUserTransaction(suspendedTransaction);
                }
            }
            if (!internalRemove) {
                // Register the entity managers
                registerEntityManagers(instance, callContext);
                // Register for synchronization callbacks
                registerSessionSynchronization(instance, callContext);
                // Setup for remove invocation
                callContext.setCurrentOperation(Operation.REMOVE);
                callContext.setCurrentAllowedStates(null);
                callContext.setInvokedInterface(callInterface);
                runMethod = beanContext.getMatchingBeanMethod(callMethod);
                callContext.set(Method.class, runMethod);
                // Do not pass arguments on home.remove(remote) calls
                final Class<?> declaringClass = callMethod.getDeclaringClass();
                if (declaringClass.equals(EJBHome.class) || declaringClass.equals(EJBLocalHome.class)) {
                    args = new Object[] {};
                }
                // Initialize interceptor stack
                final List<InterceptorData> interceptors = beanContext.getMethodInterceptors(runMethod);
                final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, runMethod, Operation.REMOVE, interceptors, instance.interceptors);
                // Invoke
                if (args == null) {
                    returnValue = interceptorStack.invoke();
                } else {
                    returnValue = interceptorStack.invoke(args);
                }
            }
        } catch (final InvalidateReferenceException e) {
            throw new ApplicationException(e.getRootCause());
        } catch (final Throwable e) {
            if (interfaceType.isBusiness()) {
                retain = beanContext.retainIfExeption(runMethod);
                handleException(callContext, txPolicy, e);
            } else {
                try {
                    handleException(callContext, txPolicy, e);
                } catch (final ApplicationException ae) {
                // Don't throw application exceptions for non-business interface removes
                }
            }
        } finally {
            if (!retain) {
                try {
                    callContext.setCurrentOperation(Operation.PRE_DESTROY);
                    final List<InterceptorData> callbackInterceptors = beanContext.getCallbackInterceptors();
                    final InterceptorStack interceptorStack = new InterceptorStack(instance.bean, null, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
                    interceptorStack.invoke();
                } catch (final Throwable callbackException) {
                    final String logMessage = "An unexpected exception occured while invoking the preDestroy method on the removed Stateful SessionBean instance; " + callbackException.getClass().getName() + " " + callbackException.getMessage();
                    /* [1] Log the exception or error */
                    logger.error(logMessage);
                } finally {
                    callContext.setCurrentOperation(Operation.REMOVE);
                }
                // todo destroy extended persistence contexts
                discardInstance(callContext);
            }
            // Commit transaction
            afterInvoke(callContext, txPolicy, instance);
        }
        return returnValue;
    } finally {
        ThreadContext.exit(oldCallContext);
    }
}
Also used : BeanTransactionPolicy(org.apache.openejb.core.transaction.BeanTransactionPolicy) SystemInstance(org.apache.openejb.loader.SystemInstance) EJBHome(javax.ejb.EJBHome) ThreadContext(org.apache.openejb.core.ThreadContext) JtaTransactionPolicy(org.apache.openejb.core.transaction.JtaTransactionPolicy) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) BeanTransactionPolicy(org.apache.openejb.core.transaction.BeanTransactionPolicy) Method(java.lang.reflect.Method) SuspendedTransaction(org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction) SessionBean(javax.ejb.SessionBean) EJBLocalHome(javax.ejb.EJBLocalHome) BeanContext(org.apache.openejb.BeanContext) InvalidateReferenceException(org.apache.openejb.InvalidateReferenceException) ApplicationException(org.apache.openejb.ApplicationException) RemoveException(javax.ejb.RemoveException) InterceptorData(org.apache.openejb.core.interceptor.InterceptorData) InterceptorStack(org.apache.openejb.core.interceptor.InterceptorStack)

Example 8 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class EntityInstanceManager method discardInstance.

public void discardInstance(final ThreadContext callContext, final EntityBean bean) throws SystemException {
    final Object primaryKey = callContext.getPrimaryKey();
    final TransactionPolicy txPolicy = callContext.getTransactionPolicy();
    if (primaryKey == null || txPolicy == null || !txPolicy.isTransactionActive()) {
        return;
    }
    // The wrapper is removed (if pooled) so that it can not be accessed again. This is
    // especially important in the obtainInstance( ) method where a disassociated wrapper
    // in the txReadyPool is indicative of an entity bean that has been removed via
    // ejbRemove() rather than freed because of an error condition as is the case here.
    final Key key = new Key(callContext.getBeanContext().getDeploymentID(), primaryKey);
    final SynchronizationWrapper wrapper = (SynchronizationWrapper) txPolicy.getResource(key);
    if (wrapper != null) {
        /*
             It's not possible to deregister a wrapper with the transaction,
             but it can be removed from the tx pool and made inoperative by
             calling its disassociate method. The wrapper will be returned to the
             wrapper pool after the transaction completes
             (see SynchronizationWrapper.afterCompletion( ) method).  The wrapper must
             be returned after the transaction completes so that it is not in the service
             of another bean when the TransactionManager calls its Synchronization methods.

             In addition, the bean instance is dereferenced so it can be garbage
             collected.
            */
        wrapper.disassociate();
    }
}
Also used : TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy)

Example 9 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class CmpContainer method businessMethod.

private Object businessMethod(final Method callMethod, final Method runMethod, final Object[] args, final ThreadContext callContext, final InterfaceType interfaceType) throws OpenEJBException {
    final BeanContext beanContext = callContext.getBeanContext();
    final TransactionPolicy txPolicy = createTransactionPolicy(beanContext.getTransactionType(callMethod, interfaceType), callContext);
    final EntityBean bean;
    Object returnValue = null;
    entrancyTracker.enter(beanContext, callContext.getPrimaryKey());
    try {
        bean = (EntityBean) cmpEngine.loadBean(callContext, callContext.getPrimaryKey());
        if (bean == null) {
            throw new NoSuchObjectException(beanContext.getDeploymentID() + " : " + callContext.getPrimaryKey());
        }
        returnValue = runMethod.invoke(bean, args);
        // when there is not transaction, merge the data from the bean back into the cmp engine
        cmpEngine.storeBeanIfNoTx(callContext, bean);
    } catch (final NoSuchObjectException e) {
        handleApplicationException(txPolicy, e, false);
    } catch (Throwable e) {
        if (e instanceof InvocationTargetException) {
            e = ((InvocationTargetException) e).getTargetException();
        }
        final ExceptionType type = callContext.getBeanContext().getExceptionType(e);
        if (type == ExceptionType.SYSTEM) {
            /* System Exception ****************************/
            handleSystemException(txPolicy, e, callContext);
        } else {
            /* Application Exception ***********************/
            handleApplicationException(txPolicy, e, type == ExceptionType.APPLICATION_ROLLBACK);
        }
    } finally {
        entrancyTracker.exit(beanContext, callContext.getPrimaryKey());
        afterInvoke(txPolicy, callContext);
    }
    return returnValue;
}
Also used : BeanContext(org.apache.openejb.BeanContext) ExceptionType(org.apache.openejb.core.ExceptionType) EntityBean(javax.ejb.EntityBean) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) EjbTransactionUtil.createTransactionPolicy(org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy) EJBLocalObject(javax.ejb.EJBLocalObject) EJBObject(javax.ejb.EJBObject) NoSuchObjectException(java.rmi.NoSuchObjectException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 10 with TransactionPolicy

use of org.apache.openejb.core.transaction.TransactionPolicy in project tomee by apache.

the class BaseContext method setRollbackOnly.

public void setRollbackOnly() throws IllegalStateException {
    doCheck(Call.setRollbackOnly);
    final ThreadContext threadContext = ThreadContext.getThreadContext();
    final BeanContext di = threadContext.getBeanContext();
    if (di.isBeanManagedTransaction()) {
        throw new IllegalStateException("bean-managed transaction beans can not access the setRollbackOnly() method");
    }
    final TransactionPolicy txPolicy = threadContext.getTransactionPolicy();
    if (txPolicy == null) {
        throw new IllegalStateException("ThreadContext does not contain a TransactionEnvironment");
    }
    if (txPolicy.getTransactionType() == TransactionType.Never || txPolicy.getTransactionType() == TransactionType.NotSupported || txPolicy.getTransactionType() == TransactionType.Supports) {
        throw new IllegalStateException("setRollbackOnly accessible only from MANDATORY, REQUIRED, or REQUIRES_NEW");
    }
    txPolicy.setRollbackOnly();
}
Also used : BeanContext(org.apache.openejb.BeanContext) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy)

Aggregations

TransactionPolicy (org.apache.openejb.core.transaction.TransactionPolicy)38 BeanContext (org.apache.openejb.BeanContext)26 EjbTransactionUtil.createTransactionPolicy (org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy)17 Method (java.lang.reflect.Method)14 EJBLocalObject (javax.ejb.EJBLocalObject)11 EJBObject (javax.ejb.EJBObject)11 EntityBean (javax.ejb.EntityBean)11 ThreadContext (org.apache.openejb.core.ThreadContext)10 InterceptorData (org.apache.openejb.core.interceptor.InterceptorData)10 InterceptorStack (org.apache.openejb.core.interceptor.InterceptorStack)10 BeanTransactionPolicy (org.apache.openejb.core.transaction.BeanTransactionPolicy)10 JtaTransactionPolicy (org.apache.openejb.core.transaction.JtaTransactionPolicy)10 ApplicationException (org.apache.openejb.ApplicationException)8 SystemInstance (org.apache.openejb.loader.SystemInstance)7 OpenEJBException (org.apache.openejb.OpenEJBException)6 ProxyInfo (org.apache.openejb.ProxyInfo)6 SystemException (org.apache.openejb.SystemException)6 Operation (org.apache.openejb.core.Operation)6 SuspendedTransaction (org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction)6 InvocationTargetException (java.lang.reflect.InvocationTargetException)5