Search code examples
jakarta-eeasynchronousglassfishejb

SFSB In SLSB with @Asynchronous Method


I am wondering if anyone here can answer my question as I have been scouring the internet looking at this stuff for a while now. I understand that you can get "unexpected results" when injecting a SFSB into a SLSB. My understanding is this is because the transaction state is lost when going from SLSB to SFSB.

My question is, if I have a Stateless bean that has only one Asynchronous business method where a injected Stateful EJB is used, then what is my downside and possible "unexpected results?"

From my understanding the Transaction state is lost anyways when the Asynchronous method is called and spun-off from another bean, only the security information is passed the Asynchronous method from above. Therefore, am I OK to inject a SFSB into my SLSB if that SFSB is only going to be used in one @Asynchronus method? What am I missing here?

Example simplified code:

@Stateless
public class SeedValuesBean {
  /**
  * Async action bean.
  */
 @EJB
 private SeedValuesAsyncBean asyncBean;

 public void performSeedValues() {
   Future<String> result = asyncBean.seedValues():
   logger.info("Result :"+ result.get());
  }
}

@Stateless
public class SeedValuesAsyncBean {

 @EJB
 private LowerBusinessBean lowerBean;  // is stateful

 @Asynchronous
 public Future<String> seedValues() {
    return new AsyncResult<>(lowerBean.getResult());
 }
}

@Stateful
public class LowerBusinessBean {
  public String getResult() {
    return Double.toString(Math.random());  
  }
}

For context I ask because if I make SeedValuesAsyncBean Stateful (so I can inject a Stateful bean and not violate the code) and then make SeedValuesBean Stateful for the same reason, I lose the asynchronous functionality and everything happens synchronously.

Thanks in advance.


Solution

    1. The downside of injecting a SFSB into a SLSB is that each invocation of your SLSB may call a different instance of it that has a different SFSB instance (with different state) injected into it. This seems like it would produce "unexpected results".
    2. Your understanding that transaction state "is lost" is somewhat fallacious. The state is lost because of item 1 above, not because of transactional instability.

    You could delegate to your SFSB through a @Singleton. You would then be guaranteed to get the same SFSB each time.