protected EntityBean getPooledInstance(ThreadContext callContext) throws OpenEJBException {
CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
Stack methodReadyPool = poolMap.get(deploymentInfo.getDeploymentID());
if (methodReadyPool == null) throw new SystemException("Invalid deployment id " + deploymentInfo.getDeploymentID() + " for this container");
EntityBean bean = (EntityBean) methodReadyPool.pop();
if (bean == null) {
try {
bean = (EntityBean) deploymentInfo.getBeanClass().newInstance();
} catch (Exception e) {
logger.error("Bean instantiation failed for class " + deploymentInfo.getBeanClass(), e);
throw new SystemException(e);
}
Operation currentOp = callContext.getCurrentOperation();
callContext.setCurrentOperation(Operation.SET_CONTEXT);
BaseContext.State[] originalStates = callContext.setCurrentAllowedStates(EntityContext.getStates());
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 (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);
callContext.setCurrentAllowedStates(originalStates);
}
} 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.
*/
Operation currentOp = callContext.getCurrentOperation();
callContext.setCurrentOperation(Operation.ACTIVATE);
BaseContext.State[] originalStates = callContext.setCurrentAllowedStates(EntityContext.getStates());
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 (Throwable e) {
logger.error("Encountered exception during call to ejbActivate()", e);
try {
Transaction tx = getTransactionManager().getTransaction();
if (tx != null) {