relationship between CDI , Stateful session bean, stateless session bean ,pojo and different scopes - ejb-3.0

Im learning j2ee , pardon me if questions appear very basic.
In httpsession session ID is stored in client side and the data associated with it is stored in server side.
When stateful session bean interacts with web client a browser makes an initial request to a Java EE web application it gets a JSESSIONID that the server can associate with a specific HTTPSession instance. By holding on to this JSESSIONID, the browser can provide it with each follow-up request and this will activate the same http session server-side.
Ref:
Using a Stateful Session Bean to track an user's session
Now when I use CDI #SessionScoped on sfb does that mean just JSESSIONID will be returned for that SFB or EJB container (?) will store another
copy of sfb on server side ?
(session.setAttribute(SFB-Another-Reference) )
Now when I use CDI #RequestScoped on sfb is it useless as SFB lives till session?
Now when I use CDI #SessionScoped on slb is it useless to use #SessionScoped since slb live only for method invocation ?
Now when I use CDI #SessionScoped on POJO
Does that mean the EJB container (?) store the pojo in session. (session.setAttribute(POJO))
Can CDI differentiate between SFB ,SLB and a POJO ?

Now when I use CDI #SessionScoped on sfb does that mean just JSESSIONID will be returned for that SFB or EJB container (?) will store another copy of sfb on server side ?
JSESSIONID is related to the http session, not to any EJB (Statless nor Stateful). When you use #SessionScoped your sfb will be associated by CDI with you http session.
Now when I use CDI #RequestScoped on sfb is it useless as SFB lives till session?
No, it is useless from other reason, as new stateful bean will be created on each request, which in effect breaks the whole idea of stateful bean, which should store state between requests.
Now when I use CDI #SessionScoped on slb is it useless to use
#SessionScoped since slb live only for method invocation ?
More or less yes. Some CDI frameworks (OWB for example) won't even allow that, and only allows #Dependent scope. SLB actually lives longer, but since it doesn't store any state its instances can be pooled and used by many clients.
Now when I use CDI #SessionScoped on POJO Does that mean the EJB
container (?) store the pojo in session. (session.setAttribute(POJO))
That POJO is associated by the CDI framework with http session, it is not directly stored in session as attribute.
Can CDI differentiate between SFB ,SLB and a POJO ?
Yes, CDI container can differentiate these and treats them differently e.g. types visibility, allowed scopes. For example fragment of the spec:
A stateless session bean must belong to the #Dependent pseudo-scope. A
singleton bean must belong to either the #ApplicationScoped scope or
to the #Dependent pseudo-scope. If a session bean specifies an illegal
scope, the container automatically detects the problem and treats it
as a definition error. A stateful session bean may have any scope.

Related

Why is injecting a Stateful Session bean in JSF/ CDI managed beans is considered bad?

Pascal Thivent mentions here that -
If you are using SFSB, then you must avoid injecting them into classes
that are multithreaded in nature, such as Servlets and JSF managed
beans (you don't want it to be shared by all clients).
Moving swiftly on, BalusC also put forwards the same thing here-, but indirectly.
....use SFSB only when you want a real stateful session bean
Consider a Session Scoped Managed bean-
#SessionScoped
public class Bean{
#EJB
EjbBean ejbBean;
}
with
#Stateful
public class EjbBean{
}
But the above SessionScoped bean will be linked to one client only and as such will have state/ instance variables different from other session scoped bean. Subsequently, any stateful EJB bean will not be shared by other clients.
Please suggest on what the author implies when he says-
you don't want it to be shared by all clients
I do perfectly understand the difference b/w HttpSession & the session word in Stateless Session Bean.

How to set few parameter in the session of a jsf/primefaces application [duplicate]

I noticed that there are different bean scopes like:
#RequestScoped
#ViewScoped
#FlowScoped
#SessionScoped
#ApplicationScoped
What is the purpose of each? How do I choose a proper scope for my bean?
Introduction
It represents the scope (the lifetime) of the bean. This is easier to understand if you are familiar with "under the covers" working of a basic servlet web application: How do servlets work? Instantiation, sessions, shared variables and multithreading.
#Request/View/Flow/Session/ApplicationScoped
A #RequestScoped bean lives as long as a single HTTP request-response cycle (note that an Ajax request counts as a single HTTP request too). A #ViewScoped bean lives as long as you're interacting with the same JSF view by postbacks which call action methods returning null/void without any navigation/redirect. A #FlowScoped bean lives as long as you're navigating through the specified collection of views registered in the flow configuration file. A #SessionScoped bean lives as long as the established HTTP session. An #ApplicationScoped bean lives as long as the web application runs. Note that the CDI #Model is basically a stereotype for #Named #RequestScoped, so same rules apply.
Which scope to choose depends solely on the data (the state) the bean holds and represents. Use #RequestScoped for simple and non-ajax forms/presentations. Use #ViewScoped for rich ajax-enabled dynamic views (ajaxbased validation, rendering, dialogs, etc). Use #FlowScoped for the "wizard" ("questionnaire") pattern of collecting input data spread over multiple pages. Use #SessionScoped for client specific data, such as the logged-in user and user preferences (language, etc). Use #ApplicationScoped for application wide data/constants, such as dropdown lists which are the same for everyone, or managed beans without any instance variables and having only methods.
Abusing an #ApplicationScoped bean for session/view/request scoped data would make it to be shared among all users, so anyone else can see each other's data which is just plain wrong. Abusing a #SessionScoped bean for view/request scoped data would make it to be shared among all tabs/windows in a single browser session, so the enduser may experience inconsitenties when interacting with every view after switching between tabs which is bad for user experience. Abusing a #RequestScoped bean for view scoped data would make view scoped data to be reinitialized to default on every single (ajax) postback, causing possibly non-working forms (see also points 4 and 5 here). Abusing a #ViewScoped bean for request, session or application scoped data, and abusing a #SessionScoped bean for application scoped data doesn't affect the client, but it unnecessarily occupies server memory and is plain inefficient.
Note that the scope should rather not be chosen based on performance implications, unless you really have a low memory footprint and want to go completely stateless; you'd need to use exclusively #RequestScoped beans and fiddle with request parameters to maintain the client's state. Also note that when you have a single JSF page with differently scoped data, then it's perfectly valid to put them in separate backing beans in a scope matching the data's scope. The beans can just access each other via #ManagedProperty in case of JSF managed beans or #Inject in case of CDI managed beans.
See also:
Difference between View and Request scope in managed beans
Advantages of using JSF Faces Flow instead of the normal navigation system
Communication in JSF2 - Managed bean scopes
#CustomScoped/NoneScoped/Dependent
It's not mentioned in your question, but (legacy) JSF also supports #CustomScoped and #NoneScoped, which are rarely used in real world. The #CustomScoped must refer a custom Map<K, Bean> implementation in some broader scope which has overridden Map#put() and/or Map#get() in order to have more fine grained control over bean creation and/or destroy.
The JSF #NoneScoped and CDI #Dependent basically lives as long as a single EL-evaluation on the bean. Imagine a login form with two input fields referring a bean property and a command button referring a bean action, thus with in total three EL expressions, then effectively three instances will be created. One with the username set, one with the password set and one on which the action is invoked. You normally want to use this scope only on beans which should live as long as the bean where it's being injected. So if a #NoneScoped or #Dependent is injected in a #SessionScoped, then it will live as long as the #SessionScoped bean.
See also:
Expire specific managed bean instance after time interval
what is none scope bean and when to use it?
What is the default Managed Bean Scope in a JSF 2 application?
Flash scope
As last, JSF also supports the flash scope. It is backed by a short living cookie which is associated with a data entry in the session scope. Before the redirect, a cookie will be set on the HTTP response with a value which is uniquely associated with the data entry in the session scope. After the redirect, the presence of the flash scope cookie will be checked and the data entry associated with the cookie will be removed from the session scope and be put in the request scope of the redirected request. Finally the cookie will be removed from the HTTP response. This way the redirected request has access to request scoped data which was been prepared in the initial request.
This is actually not available as a managed bean scope, i.e. there's no such thing as #FlashScoped. The flash scope is only available as a map via ExternalContext#getFlash() in managed beans and #{flash} in EL.
See also:
How to show faces message in the redirected page
Pass an object between #ViewScoped beans without using GET params
CDI missing #ViewScoped and #FlashScoped
Since JSF 2.3 all the bean scopes defined in package javax.faces.bean package have been deprecated to align the scopes with CDI. Moreover they're only applicable if your bean is using #ManagedBean annotation. If you are using JSF versions below 2.3 refer to the legacy answer at the end.
From JSF 2.3 here are scopes that can be used on JSF Backing Beans:
1. #javax.enterprise.context.ApplicationScoped: The application scope persists for the entire duration of the web application. That scope is shared among all requests and all sessions. This is useful when you have data for whole application.
2. #javax.enterprise.context.SessionScoped: The session scope persists from the time that a session is established until session termination. The session context is shared between all requests that occur in the same HTTP session. This is useful when you wont to save data for a specific client for a particular session.
3. #javax.enterprise.context.ConversationScoped: The conversation scope persists as log as the bean lives. The scope provides 2 methods: Conversation.begin() and Conversation.end(). These methods should called explicitly, either to start or end the life of a bean.
4. #javax.enterprise.context.RequestScoped: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back to the client. If you place a managed bean into request scope, a new instance is created with each request. It is worth considering request scope if you are concerned about the cost of session scope storage.
5. #javax.faces.flow.FlowScoped: The Flow scope persists as long as the Flow lives. A flow may be defined as a contained set of pages (or views) that define a unit of work. Flow scoped been is active as long as user navigates with in the Flow.
6. #javax.faces.view.ViewScoped: A bean in view scope persists while the same JSF page is redisplayed. As soon as the user navigates to a different page, the bean goes out of scope.
The following legacy answer applies JSF version before 2.3
As of JSF 2.x there are 4 Bean Scopes:
#SessionScoped
#RequestScoped
#ApplicationScoped
#ViewScoped
Session Scope: The session scope persists from the time that a session is established until session termination. A session terminates
if the web application invokes the invalidate method on the
HttpSession object, or if it times out.
RequestScope: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back
to the client. If you place a managed bean into request scope, a new
instance is created with each request. It is worth considering request
scope if you are concerned about the cost of session scope storage.
ApplicationScope: The application scope persists for the entire duration of the web application. That scope is shared among all
requests and all sessions. You place managed beans into the
application scope if a single bean should be shared among all
instances of a web application. The bean is constructed when it is
first requested by any user of the application, and it stays alive
until the web application is removed from the application server.
ViewScope: View scope was added in JSF 2.0. A bean in view scope persists while the same JSF page is redisplayed. (The JSF
specification uses the term view for a JSF page.) As soon as the user
navigates to a different page, the bean goes out of scope.
Choose the scope you based on your requirement.
Source: Core Java Server Faces 3rd Edition by David Geary & Cay Horstmann [Page no. 51 - 54]

Using a CDI #SessionScoped bean from a WebSocket #ServerEndpoint

In a web application, users use a servlet HTTP session. Some data are stored in CDI #SessionScoped beans. Later in some pages WebSocket communications are performed between the user browser and the server.
With GlassFish 4, when using an injected #SessionScoped CDI bean from a WebSocket #ServerEndpoint with GlassFish 4.0 I get an error message:
org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.SessionScoped
From JSP/servlet type requests, using the #SessionScoped CDI bean is fine, but not from the WebSocket #ServerEndpoint.
Also note that using #Singleton CDI beans from the #ServerEndpoint works fine, so this is not a general purpose dependency injection problem.
Maybe I did something wrong.
So my questions is can #SessionScoped CDI beans be used from methods of WebSocket #ServerEndpoint beans? If yes, how?
Thank you for your time.
It may not be the exact same question, but the issue is similar enough that the answers there apply here. Basically, as #JoakimErdfelt notes websocket support for CDI is problematic at best. The websocket spec neglected to mention what scopes are active.
Out of the box, this is what Tyrus supports: https://github.com/tyrus-project/tyrus/tree/master/samples/cdi/src/main/java/org/glassfish/tyrus/sample/cdi
If you want, you can extend it to start a session scope (for reference, Apache DeltaSpike's CDI Context Control), but because of the protocol difference it would be a different session than the one already established via HTTP.

Returning status from long-running session bean method

I am using JSF 2.0 with RichFaces 4.2.2 running on Glassfish 3.1.2. I have created local stateless session beans with a long-running method that will be called by the JSF managed bean.
I would like to be able to push status information from the session bean back to the managed bean so that I can use something like RichFaces a4j:push to get the status to the browser. I believe this would require that the call to the session bean method would be asynchronous. Are there patterns for pushing information from session beans back to the front end as the session bean is processing the method call?
Stateless session beans (SLSB) are not supposed to hold any state (read: instance variables which are altered by the methods) because they are shared between all clients applicationwide. So they are useless to you if you need a session bean with some state which you can update during the process and which the client can request anytime. You need a stateful session bean (SFSB) instead. If you inject the SFSB in a session scoped JSF managed bean, then you'll be able to request the proper status from it and push it to the client throughout the HTTP session.
To understand the difference between SLSB and SFSB better, you may find this answer helpful: JSF request scoped bean keeps recreating new Stateful session beans on every request?

How does #SessionScoped work with EJB? Is CDI only for web-tier?

How is the session defined in #SessionScoped CDI bean?
Is this annotation valid only when called from Servlet container, where the session is well defined in form of HttpSession?
If not, than how an EJB with #Inject #SessionScoped MyBean myBean can know what the session really is? I mean, methods of this EJB could have been invoked by a standalone client, RESTful WS or by some other view.
What should happen in such case? Should the annotation have no meaning, should it inject fresh MyBean instance for each request or maybe it should retain the same instance across all requests?
Taken from the #SessionScoped specification
The session scope is active:
during the service() method of any servlet in the web application,
during the doFilter() method of any servlet filter and when the
container calls any HttpSessionListener, AsyncListener or
ServletRequestListener.
So in short, yes. It is bound to the HttpSession. Also:
The session context is shared between all servlet requests that occur
in the same HTTP session. The session context is destroyed when the
HTTPSession times out, after all HttpSessionListeners have been
called, and at the very end of any request in which invalidate() was
called, after all filters and ServletRequestListeners have been
called.

Resources