Replacing a managed bean - jsf-2

Couple of questions on setting managed bean using CDI.
1. If a session bean is Injected into another using #Inject annotation, how to replace the entire session Bean?
2. In CDI, Is it possible to define Injection to only inject (not to outject).

If a session bean is Injected into another using #Inject annotation, how to replace the entire session Bean?
You don't. This requirement can mean only 1 thing: the session scope is the wrong scope for the bean in question. Perhaps you're looking for the conversation scope instead.
If you really need to, you can always add some clear() method which clears the state (thus, all of its properties) of the session scoped bean, but this is still fishy. Just choose the right scope from the beginning on.

Related

CDI Keeps all Injected tree references of SessionScoped beans?

I am starting a new project with JavaEE 7 and declared a Sessionscoped bean to maintain the web logged user information in session.
The UserSessionBean, as I named it, is intended to be lightweight - trying to avoid lots of data to be kept in the session by Weld. But in some cases I need to get all user information, so added a getUser() method which must query and retrieve a UserEntity from JPA. In order for the method to do its job, I need to #Inject other resources onto the UserSessionBean.
My question is: These dependant resources will be kept and serialised within the UserSessionBean by Weld until the context is destroyed?
The weld documentation says this:
An instance of a dependent bean is never shared between different
clients or different injection points. It is strictly a dependent
object of some other object. It is instantiated when the object it
belongs to is created, and destroyed when the object it belongs to is
destroyed.
That makes me think the all SessionBean tree is kept by weld during session life, but how can I keep a lightweight SessionBean and use injected CDI resources on it?
Since what you're injecting are also CDI beans, it is not the beans themselves that get serialised, but their lightweight proxies. Upon deserialisation, the proxies dynamically resolve the correct beans for whatever scope they are. See section 5.4 Client Proxies of the CDI1.0 spec. Hence, your bean is as lightweight as possible.

Why use a ShoppingCart as a Stateful Sesson Bean?

One typical example of using a Stateful Session Bean is through a ShoppingCart example. We create a bean instance of the ShoppingCart class, then store this instance within a HttpSession.
However, the same can be achieved easily with the ShoppingCart class being a normal Java class (or a stateless session bean). A request of adding a product comes in, we create a cart object, then put that cart object inside a HttpSession.
So, I don't see the point of using a stateful session bean ShoppingCart here. And in general, a stateful session bean doesn't seem to play any significant roles.
I would rephrase your question:
Why should I use mechanism for automatic session based bean management (maintaining one instance per session, persisting inside session) if I can implement it myself?
Yes, you can implement it yourself and it would be pretty simple. However you can just use Java EE mechanisms for that.

Setup an ObjectPool Bean with JSF-2

I want to create a JSF-2 Portlet with multiple SessionScoped Backing Beans. I'd also like them all to share some POJOs with a common SessionScoped Bean that will serve as an Object Pool.
I have two issues troubling me:
I'd like to have this bean Initialized before any of the Backing Beans. Note that no xhtml page will call an object directly to the Object Pool Bean, so at least one Backing Bean will be init before the ObjectPool. Is there some way to make sure it will be init first, except that calling in in PostConstruct of every other Backing Bean ?
I am confused on using ManagedProperties, because I need All the Backing beans to call the Object Pool's properties, while I also need the Backing Bean to call some Client / BackingBean functions. How can I do that without creating double references ?
For your first question you can use a f:prerenderView in your
login xhtml page. #SessionScoped beans are not created until you
reference them from the page or create them by yourself and store in
the context. If you link the f:prerenderView to some of your method
of the bean which acts like a pool it will be initialized for the
rest of the HttpSession. You can later inject it in your other
#SessionScoped beans using #ManagedProperty annotation.
About your second question, just remember you're not forced to go
through the view beans in order to obtain session properties. Haven't
you made the Object Pool itself a #ManagedBean? So access it
directly from your page!

CDI when injectionpoint.getBean() can be null

I'm playing with CDI producers and spotted in doc that
InjectionPoint.getBean()
can return null if the injection point does not belong to a bean.
What does it effectively mean? How can injection point not belong to a bean? Is it possible to inject something into something other what is not CDI bean?
I'd like to get class name of class containing this injection point and now I don't know if I can rely on getBean() method if it can return null?
Chances are VERY good (AFAIK) you'd only see a null if you manually created an InjectionPoint through an extension.

What happens to #SessionScoped #ManagedBean which is already in HttpSession?

Old code creates a #SessionScoped #ManagedBean (namely UserSession) at the first request in a ServletFilter and puts it in the HttpSession (if not already there).
Now what happens when some EL expression tries to access that ManagedBean the first time? I expected a second instance of UserSession (one created manually and one from JSF). So I instrumented the constructor, #PostConstruct and #PreDestroy with a few logging statements. Now it seems JSF never creates the UserSession - only the constructor is called.
Is this possible? Can JSF reuse that bean from HttpSession? Is it legit to put #SessionScoped beans in HttpSession?
Your observation is correct. Under JSF's covers, JSF itself also stores session scoped managed beans as an attribute of the HttpSession. So if it's already present, it will just be reused, regardless of the way how it has ended up in there.
Whether that's good or bad depends on the concrete functional requirement. Given your astonishment, I'd guess that it's bad and that you need to revise either the approach or the functional requirement. Perhaps you need a secondary (session scoped?) managed bean which injects the particular session attribute by #ManagedProperty.

Resources