}
final Component component = context.getPrivateData(Component.class);
if (!(component instanceof EntityBeanComponent)) {
throw MESSAGES.unexpectedComponent(component, EntityBeanComponent.class);
}
final EntityBeanComponent entityBeanComponent = (EntityBeanComponent) component;
//grab an unasociated entity bean from the pool
final EntityBeanComponentInstance instance = entityBeanComponent.getPool().get();
//call the ejbCreate method
final Object primaryKey = invokeEjbCreate(context, ejbCreate, instance, params);
instance.associate(primaryKey);
primaryKeyReference.set(primaryKey);
//now add the instance to the cache, so it is usable
//note that we do not release it back to the pool
//the cache will do that when it is expired or removed
boolean synchronizationRegistered = false;
boolean exception = false;
entityBeanComponent.getCache().create(instance);
//we reference the entity immedietly
//and release our reference once the create method or the current tx finishes
entityBeanComponent.getCache().reference(instance);
try {
invokeEjbPostCreate(context, ejbPostCreate, instance, params);
//if a transaction is active we register a sync
//and if the transaction is rolled back we release the instance back into the pool
final TransactionSynchronizationRegistry transactionSynchronizationRegistry = entityBeanComponent.getTransactionSynchronizationRegistry();
if (transactionSynchronizationRegistry.getTransactionKey() != null) {
transactionSynchronizationRegistry.registerInterposedSynchronization(new Synchronization() {
@Override
public void beforeCompletion() {
}
@Override
public void afterCompletion(final int status) {
entityBeanComponent.getCache().release(instance, status == Status.STATUS_COMMITTED);
if (status != Status.STATUS_COMMITTED) {
entityBeanComponent.getPool().release(instance);
}
}
});
synchronizationRegistered = true;
}
return context.proceed();
} catch (Exception e) {
entityBeanComponent.getCache().release(instance, false);
throw e;
} finally {
if (!synchronizationRegistered && !exception) {
entityBeanComponent.getCache().release(instance, true);
}
}
}