I have a Stateful Session Bean (SFSB) which acts as authentication module. In the SFSB I store the current user that is logged in. Moreover I have some facades (which are Stateless Session Beans (SLSB)) that handles the JPA/SQL stuff for my entities. In order to check the access permissions of the current user, I try to call the SFSB out of the SLSB. But the current user field is always "null" when called from SLSB. When calling the SFSB directly, the current user field is set correctly... For calling I use the @EJB annotation.
Any ideas what the problem might be? Is that somehow a context problem? Is it generally possible to call a SFSB from SLSB preserving it's state?
Many thanks in advance!
You shouldn't call a stateful session bean from a stateless session bean.
Here is some reading: JEE6 Tutorial - Session Beans
Stateless beans don't know anything about your session. Any time you call it, it is stateless. Then it calls a stateful session bean. No surprise it doesn't have any context relating to the state of the client's session because it is called from stateless object.
I don't know if it will work, but you possibly could try to get the context by doing a JNDI lookup instead of DI using the @EJB notation. Something like this in the stateless ejb might work. You'll probably have to play with it and I can't guarantee anything. It should get the context of the client calling the stateless ejb. The client will need to have session context/scope or forget it.
@Resource SessionContext sessionContext; MyStatefulBean msb = (MyStatefulBean)sessionContext.lookup("ejb/MyStatefulBean"); msb.doSomething(fubar);
It is better to call the stateful session bean from a client that has a session scope or from another stateful ejb. Stateless and stateful have different reasons for being.
You should not inject a stateful EJB into a stateless EJB. This can have very unpredicatable consequences, because lifecycle of a stateful EJB is started when injected and managed by owning bean. In the worst case, stateless EJB can be reused by application server for different users, which would then access the same stateful EJB. In your case, a user would be identified as a different user.
Most probably you want to associate a stateful EJB with current HTTP session, which is not done automatically as many people suppose. For more details read section named EJB 3 Is Not Contextual here: Contexts and Dependency Injection article
In order to associate a stateful EJB with the session, you need to inject stateful EJB into session scoped CDI bean, which can be injected freely into a stateless bean - actually only a stub is injected and session scoped bean (together with the stateful EJB) is created for every new session.
Maybe even better approach is to extract interface of the stateful bean, and use a CDI producer to create a session scoped implementation of the sateful bean. This way you can also handle the case, when a stateful EJB is automatically removed on an exception in the EJB. In such case, you may want to recreate the EJB within the same session.
If you inject the stateful session bean inside stateless bean by look-up also does not work because new instance will be created for stateful bean so it does not hold any values like logged user information and etc...