Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE 6: How to call Stateful Session Bean from Stateless Session Bean?

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!

like image 373
salocinx Avatar asked Jul 11 '12 16:07

salocinx


People also ask

What is the valid reason behind a stateful session bean instead of a stateless session bean?

The main difference between Stateless and Stateful Session Bean is that Stateless Session Bean is a business object without state (data) that describes the business logic while Stateful Session Bean is a business object with a state (data) that describes the business logic.

What is session bean differentiate between stateful session bean and stateless session bean?

An instance of a stateful session bean has a unique identity that is assigned by the container at create time. Stateless: A stateless session bean does not maintain conversational state. Instances of a stateless session bean have no conversational state.

Which session bean maintains state between clients?

Singleton session beans maintain their state between client invocations but are not required to maintain their state across server crashes or shutdowns.

Which session bean does the conversational state between multiple?

Stateful Session Beans The state of an object consists of the values of its instance variables. In a stateful session bean, the instance variables represent the state of a unique client-bean session. Because the client interacts ("talks") with its bean, this state is often called the conversational state.


2 Answers

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.

like image 112
Bill Rosmus Avatar answered Oct 09 '22 15:10

Bill Rosmus


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.

like image 43
OndroMih Avatar answered Oct 09 '22 15:10

OndroMih