Search in sources :

Example 21 with EntityBean

use of javax.ejb.EntityBean in project tomee by apache.

the class JpaCmpEngine method executeSelectQuery.

private List<Object> executeSelectQuery(final Query query, Object[] args) {
    // process args
    if (args == null) {
        args = NO_ARGS;
    }
    for (int i = 0; i < args.length; i++) {
        Object arg = args[i];
        // ejb proxies need to be swapped out for real instance classes
        if (arg instanceof EJBObject) {
            arg = Cmp2Util.getEntityBean((EJBObject) arg);
        }
        if (arg instanceof EJBLocalObject) {
            arg = Cmp2Util.getEntityBean((EJBLocalObject) arg);
        }
        try {
            query.getParameter(i + 1);
        } catch (final IllegalArgumentException e) {
            // specified position does not exist
            continue;
        }
        query.setParameter(i + 1, arg);
    }
    // todo results should not be iterated over, but should instead
    // perform all work in a wrapper list on demand by the application code
    final List results = query.getResultList();
    for (final Object value : results) {
        if (value instanceof EntityBean) {
            // todo don't activate beans already activated
            final EntityBean entity = (EntityBean) value;
            cmpCallback.setEntityContext(entity);
            cmpCallback.ejbActivate(entity);
        }
    }
    // noinspection unchecked
    return results;
}
Also used : EJBObject(javax.ejb.EJBObject) EntityBean(javax.ejb.EntityBean) EJBObject(javax.ejb.EJBObject) EJBLocalObject(javax.ejb.EJBLocalObject) List(java.util.List) EJBLocalObject(javax.ejb.EJBLocalObject)

Example 22 with EntityBean

use of javax.ejb.EntityBean in project tomee by apache.

the class EntityContainer method invoke.

protected Object invoke(final InterfaceType type, final Method callMethod, final Method runMethod, final Object[] args, final ThreadContext callContext) throws OpenEJBException {
    final BeanContext beanContext = callContext.getBeanContext();
    final TransactionPolicy txPolicy = createTransactionPolicy(beanContext.getTransactionType(callMethod, type), callContext);
    EntityBean bean = null;
    Object returnValue = null;
    entrancyTracker.enter(callContext.getBeanContext(), callContext.getPrimaryKey());
    try {
        bean = instanceManager.obtainInstance(callContext);
        ejbLoad_If_No_Transaction(callContext, bean);
        returnValue = runMethod.invoke(bean, args);
        ejbStore_If_No_Transaction(callContext, bean);
        instanceManager.poolInstance(callContext, bean, callContext.getPrimaryKey());
    } catch (final Throwable e) {
        handleException(txPolicy, e, callContext, bean);
    } finally {
        entrancyTracker.exit(callContext.getBeanContext(), callContext.getPrimaryKey());
        afterInvoke(txPolicy, callContext);
    }
    return returnValue;
}
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) EJBObject(javax.ejb.EJBObject) EJBLocalObject(javax.ejb.EJBLocalObject)

Example 23 with EntityBean

use of javax.ejb.EntityBean in project tomee by apache.

the class EntityInstanceManager method obtainInstance.

public EntityBean obtainInstance(final ThreadContext callContext) throws OpenEJBException {
    // primary key is null if its a servicing a home methods (create, find, ejbHome)
    final Object primaryKey = callContext.getPrimaryKey();
    final TransactionPolicy txPolicy = callContext.getTransactionPolicy();
    if (callContext.getPrimaryKey() != null && txPolicy != null && txPolicy.isTransactionActive()) {
        final Key key = new Key(callContext.getBeanContext().getDeploymentID(), primaryKey);
        SynchronizationWrapper wrapper = (SynchronizationWrapper) txPolicy.getResource(key);
        if (wrapper != null) {
            if (!wrapper.isAssociated()) {
                /*
                    * If the bean identity was removed (via ejbRemove()) within the same transaction,
                    * then it's SynchronizationWrapper will be in the txReady pool but marked as disassociated.
                    * This allows us to prevent a condition where the caller removes the bean and then attempts to
                    * call a business method on that bean within the same transaction.  After a bean is removed any
                    * subsequent invocations on that bean with the same transaction should throw a NoSuchEntityException.
                    * its likely that the application server would have already made the reference invalid, but this bit of
                    * code is an extra precaution.
                    */
                throw new InvalidateReferenceException(new NoSuchObjectException("Entity not found: " + primaryKey));
            } else if (callContext.getCurrentOperation() == Operation.REMOVE) {
                /*
                    *  To avoid calling ejbStore( ) on a bean that after its removed, we can not delegate
                    *  the wrapper is marked as disassociated from the transaction to avoid processing the
                    *  beforeCompletion( ) method on the SynchronizationWrapper object.
                    */
                wrapper.disassociate();
            }
            if (wrapper.isAvailable() || wrapper.primaryKey.equals(primaryKey)) {
                return wrapper.getEntityBean();
            } else {
                // its simpler to implement.
                return wrapper.getEntityBean();
            }
        } else {
            /*
                * If no synchronized wrapper for the key exists
                * Then the bean entity is being access by this transaction for the first time,
                * so it needs to be enrolled in the transaction.
                */
            final EntityBean bean = getPooledInstance(callContext);
            wrapper = new SynchronizationWrapper(callContext.getBeanContext(), primaryKey, bean, false, key, txPolicy);
            if (callContext.getCurrentOperation() == Operation.REMOVE) {
                /*
                    *  To avoid calling ejbStore( ) on a bean that after its removed, we can not delegate
                    *  the wrapper is marked as disassociated from the transaction to avoid processing the
                    *  beforeCompletion( ) method on the SynchronizationWrapper object.
                    *
                    *  We have to still use a wrapper so we can detect when a business method is called after
                    *  a ejbRemove() and act to prevent it from being processed.
                    */
                wrapper.disassociate();
            }
            txPolicy.registerSynchronization(wrapper);
            loadingBean(bean, callContext);
            final Operation orginalOperation = callContext.getCurrentOperation();
            callContext.setCurrentOperation(Operation.LOAD);
            try {
                bean.ejbLoad();
            } catch (final NoSuchEntityException e) {
                wrapper.disassociate();
                throw new InvalidateReferenceException(new NoSuchObjectException("Entity not found: " + primaryKey, e));
            } catch (final Exception e) {
                logger.error("Exception encountered during ejbLoad():", e);
                // djencks not sure about this dissociate call
                wrapper.disassociate();
                throw new OpenEJBException(e);
            } finally {
                callContext.setCurrentOperation(orginalOperation);
            }
            txPolicy.putResource(key, wrapper);
            return bean;
        }
    } else {
        // returned to the pool -- depending on if the tx is a client initiated or container initiated.
        return getPooledInstance(callContext);
    }
}
Also used : InvalidateReferenceException(org.apache.openejb.InvalidateReferenceException) OpenEJBException(org.apache.openejb.OpenEJBException) EntityBean(javax.ejb.EntityBean) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) NoSuchObjectException(org.apache.openejb.core.NoSuchObjectException) Operation(org.apache.openejb.core.Operation) NoSuchEntityException(javax.ejb.NoSuchEntityException) OpenEJBException(org.apache.openejb.OpenEJBException) NoSuchObjectException(org.apache.openejb.core.NoSuchObjectException) RemoteException(java.rmi.RemoteException) InvalidateReferenceException(org.apache.openejb.InvalidateReferenceException) SystemException(org.apache.openejb.SystemException) TransactionRolledbackException(org.apache.openejb.core.transaction.TransactionRolledbackException) ApplicationException(org.apache.openejb.ApplicationException) NoSuchEntityException(javax.ejb.NoSuchEntityException)

Example 24 with EntityBean

use of javax.ejb.EntityBean in project tomee by apache.

the class EntityInstanceManager method getPooledInstance.

protected EntityBean getPooledInstance(final ThreadContext callContext) throws OpenEJBException {
    final BeanContext beanContext = callContext.getBeanContext();
    final Stack methodReadyPool = poolMap.get(beanContext.getDeploymentID());
    if (methodReadyPool == null) {
        throw new SystemException("Invalid deployment id " + beanContext.getDeploymentID() + " for this container");
    }
    EntityBean bean = (EntityBean) methodReadyPool.pop();
    if (bean == null) {
        try {
            bean = (EntityBean) beanContext.getBeanClass().newInstance();
        } catch (final Exception e) {
            logger.error("Bean instantiation failed for class " + beanContext.getBeanClass(), e);
            throw new SystemException(e);
        }
        final Operation currentOp = callContext.getCurrentOperation();
        callContext.setCurrentOperation(Operation.SET_CONTEXT);
        try {
            /*
                * setEntityContext executes in an unspecified transactional context. In this case we choose to
                * allow it to have what every transaction context is current. Better then suspending it
                * unnecessarily.
                *
                * We also chose not to invoke EntityContainer.invoke( ) method, which duplicate the exception handling
                * logic but also attempt to manage the begining and end of a transaction. It its a container managed transaciton
                * we don't want the TransactionScopeHandler commiting the transaction in afterInvoke() which is what it would attempt
                * to do.
                */
            bean.setEntityContext(createEntityContext());
        } catch (final Exception e) {
            /*
                * The EJB 1.1 specification does not specify how exceptions thrown by setEntityContext impact the
                * transaction, if there is one.  In this case we choose the least disruptive operation, throwing an
                * application exception and NOT automatically marking the transaciton for rollback.
                */
            logger.error("Bean callback method failed ", e);
            throw new ApplicationException(e);
        } finally {
            callContext.setCurrentOperation(currentOp);
        }
    } else {
        reusingBean(bean, callContext);
    }
    if (callContext.getCurrentOperation() == Operation.BUSINESS || callContext.getCurrentOperation() == Operation.REMOVE) {
        /*
            * When a bean is retrieved from the bean pool to service a client's business method request it must be
            * notified that its about to enter service by invoking its ejbActivate( ) method. A bean instance
            * does not have its ejbActivate() invoked when:
            * 1. Its being retreived to service an ejbCreate()/ejbPostCreate().
            * 2. Its being retrieved to service an ejbFind method.
            * 3. Its being retrieved to service an ejbRemove() method.
            * See section 9.1.4 of the EJB 1.1 specification.
            */
        final Operation currentOp = callContext.getCurrentOperation();
        callContext.setCurrentOperation(Operation.ACTIVATE);
        try {
            /*
                In the event of an exception, OpenEJB is required to log the exception, evict the instance,
                and mark the transaction for rollback.  If there is a transaction to rollback, then the a
                javax.transaction.TransactionRolledbackException must be throw to the client.
                See EJB 1.1 specification, section 12.3.2
                */
            bean.ejbActivate();
        } catch (final Throwable e) {
            logger.error("Encountered exception during call to ejbActivate()", e);
            final TransactionPolicy txPolicy = callContext.getTransactionPolicy();
            if (txPolicy != null && txPolicy.isTransactionActive()) {
                txPolicy.setRollbackOnly(e);
                throw new ApplicationException(new TransactionRolledbackException("Reflection exception thrown while attempting to call ejbActivate() on the instance", e));
            }
            throw new ApplicationException(new RemoteException("Exception thrown while attempting to call ejbActivate() on the instance. Exception message = " + e.getMessage(), e));
        } finally {
            callContext.setCurrentOperation(currentOp);
        }
    }
    return bean;
}
Also used : BeanContext(org.apache.openejb.BeanContext) ApplicationException(org.apache.openejb.ApplicationException) SystemException(org.apache.openejb.SystemException) EntityBean(javax.ejb.EntityBean) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) Operation(org.apache.openejb.core.Operation) TransactionRolledbackException(org.apache.openejb.core.transaction.TransactionRolledbackException) RemoteException(java.rmi.RemoteException) OpenEJBException(org.apache.openejb.OpenEJBException) NoSuchObjectException(org.apache.openejb.core.NoSuchObjectException) RemoteException(java.rmi.RemoteException) InvalidateReferenceException(org.apache.openejb.InvalidateReferenceException) SystemException(org.apache.openejb.SystemException) TransactionRolledbackException(org.apache.openejb.core.transaction.TransactionRolledbackException) ApplicationException(org.apache.openejb.ApplicationException) NoSuchEntityException(javax.ejb.NoSuchEntityException) LinkedListStack(org.apache.openejb.util.LinkedListStack) Stack(org.apache.openejb.util.Stack)

Example 25 with EntityBean

use of javax.ejb.EntityBean in project tomee by apache.

the class CmpContainer method createEJBObject.

private ProxyInfo createEJBObject(final Method callMethod, 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 primaryKey = null;
    try {
        // Obtain a bean instance from the method ready pool
        bean = createNewInstance(callContext);
        // set the entity context
        setEntityContext(bean);
        // Obtain the proper ejbCreate() method
        final Method ejbCreateMethod = beanContext.getMatchingBeanMethod(callMethod);
        // Set current operation for allowed operations
        callContext.setCurrentOperation(Operation.CREATE);
        // Invoke the proper ejbCreate() method on the instance
        ejbCreateMethod.invoke(bean, args);
        // create the new bean
        primaryKey = cmpEngine.createBean(bean, callContext);
        // determine post create callback method
        final Method ejbPostCreateMethod = beanContext.getMatchingPostCreateMethod(ejbCreateMethod);
        // create a new context containing the pk for the post create call
        final ThreadContext postCreateContext = new ThreadContext(beanContext, primaryKey);
        postCreateContext.setCurrentOperation(Operation.POST_CREATE);
        final ThreadContext oldContext = ThreadContext.enter(postCreateContext);
        try {
            // Invoke the ejbPostCreate method on the bean instance
            ejbPostCreateMethod.invoke(bean, args);
        // According to section 9.1.5.1 of the EJB 1.1 specification, the "ejbPostCreate(...)
        // method executes in the same transaction context as the previous ejbCreate(...) method."
        // 
        // The bean is first insterted using db.create( ) and then after ejbPostCreate( ) its
        // updated using db.update(). This protocol allows for visablity of the bean after ejbCreate
        // within the current trasnaction.
        } finally {
            ThreadContext.exit(oldContext);
        }
        // when there is not transaction, merge the data from the bean back into the cmp engine
        cmpEngine.storeBeanIfNoTx(callContext, bean);
    } 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 {
        afterInvoke(txPolicy, callContext);
    }
    return new ProxyInfo(beanContext, primaryKey);
}
Also used : BeanContext(org.apache.openejb.BeanContext) ExceptionType(org.apache.openejb.core.ExceptionType) ProxyInfo(org.apache.openejb.ProxyInfo) EntityBean(javax.ejb.EntityBean) ThreadContext(org.apache.openejb.core.ThreadContext) TransactionPolicy(org.apache.openejb.core.transaction.TransactionPolicy) EjbTransactionUtil.createTransactionPolicy(org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy) EJBLocalObject(javax.ejb.EJBLocalObject) EJBObject(javax.ejb.EJBObject) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Aggregations

EntityBean (javax.ejb.EntityBean)25 EJBLocalObject (javax.ejb.EJBLocalObject)13 EJBObject (javax.ejb.EJBObject)12 FinderException (javax.ejb.FinderException)12 RemoteException (java.rmi.RemoteException)11 BeanContext (org.apache.openejb.BeanContext)11 TransactionPolicy (org.apache.openejb.core.transaction.TransactionPolicy)11 EJBException (javax.ejb.EJBException)10 NoSuchEntityException (javax.ejb.NoSuchEntityException)10 RemoveException (javax.ejb.RemoveException)9 EjbTransactionUtil.createTransactionPolicy (org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy)9 CreateException (javax.ejb.CreateException)8 NoSuchObjectLocalException (javax.ejb.NoSuchObjectLocalException)8 SystemException (javax.transaction.SystemException)7 EjbInvocation (com.sun.ejb.EjbInvocation)4 InvocationTargetException (java.lang.reflect.InvocationTargetException)4 ObjectNotFoundException (javax.ejb.ObjectNotFoundException)4 OpenEJBException (org.apache.openejb.OpenEJBException)4 ProxyInfo (org.apache.openejb.ProxyInfo)4 EJBLocalRemoteObject (com.sun.ejb.containers.EJBLocalRemoteObject)3