Is it possible to access a stateful session bean inside a stateless bean?
My problem is that I have a session bean called User and I want to access user info inside a stateless bean...
I am trying like this:
@Stateless
public class OfferManagerBean implements OfferManagerLocal, OfferManager
{
@Resource
private SessionContext context;
@EJB
private ro.project.ejb.interfaces.User user;
public String getUsername()
{
user = (ro.project.ejb.interfaces.User) context.lookup("java:global/project/projectEJB/User!ro.project.ejb.interfaces.User");
return user.getUsername();
}
User user = (User) ctx.lookup("java:global/project/projectEJB/User!ro.project.ejb.interfaces.User");
user.setUsername("Alex");
OfferManager offerManager = (OfferManager) ctx.lookup("java:global/project/projectEJB/OfferManagerBean!ro.project.ejb.interfaces.OfferManager");
assertEquals(offerManager.getUsername(), "Alex");
The result of this test case is java.lang.AssertionError: expected:<null> but was:<Alex>
it fails.. It seems that how I am requesting the stateful bean is returning me a new instance...
I am asking almost the same thing this guy is asking: Concept for reusable login session in rmi ejb calls
I want to do that but not with JAAS...
Thank you in advance
You should never inject a @Stateful
bean (SFSB) in a @Stateless
bean (SLSB). A SFSB lives as long as its client lives (the client is the instance where the SFSB is been injected, which is in this case the SLSB itself). SLSB's are however intented to be stateless and most containers have them in a pool. So whenever the SLSB goes back to the pool after use, it will be reused entirely elsewhere, but it holds the same SFSB instance as it was when the SLSB was been created for the first time! This may lead to undesireable results.
Also, everytime when you get the SFSB from JNDI, you will get a brand new instance which is unlike SLSBs not shared elsewhere. The SFSB's client is then the current client class instance where you've got the SFSB from JNDI. You're supposed to keep hold of this instance yourself and reuse the very same instance until you're finished with performing the transaction on it. One of the ways is storing it in the HTTP session yourself or in a session scoped managed bean of the MVC framework you're using.
The functional requirement is not entirely clear to me, so it's hard to give a suitable answer how to solve your particular problem, but I have the impression that you actually need to store the user in the HTTP session, not in a SFSB. The most common beginner's mistake as to session beans is namely that they incorrectly interpret the "session" in EJB context as being the HTTP session.
See also this related answer on a question of the same kind for a more in-depth explanation: JSF request scoped bean keeps recreating new Stateful session beans on every request? According to your question history you're familiar with JSF, so this answer should be easy understandable.
In general it is possible to access certain existing stateful session bean inside stateless bean. It can be for example given as argument to the business method of stateless session bean.
But what you are trying cannot work. Reason is that both, dependendy injection (@EJB ) and lookup (ctx.lookup...) are guaranteed to call newInstance and as consequence you will have new instance.
This is explained in specification with following words:
A session bean instance’s life starts when a client obtains a reference to a stateful session bean instance through dependency injection or JNDI lookup, or when the client invokes a create method on the session bean’s home interface. This causes the container to invoke newInstance on the session bean class to create a new session bean instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With