Why should we make a SessionScoped ManagedBean thread safe in JSF? - jsf

I know that Application-Scope persists across multiple users, so it's obvious that we should make sure that all the ApplicationScoped ManagedBeans are thread safe.
I also understand that we don't need to care about thread safety for a RequestScoped ManagedBean. That's because it last only for one HTTP request, and is newly instantiated for each request if it's referenced.
But I am not quite sure why we should worry about thread safety for a SessionScoped ManangedBean. Even though it persists across multiple requests, each individual user gets his/her own instance of it, right?
So, why do we need to worry about thread safety in case of SessionScoped ManagedBeand, and does that apply to ViewScoped ManagedBean too? ViewScope persists across 2 consecutive requests for the same view, right?

If you already worry about the threadsafety of the data in a certain scope, then the data most likely belongs in a more narrow scope (i.e. there is a flaw in the high level design). If the data is been put in the right scope, then there's totally no reason to worry about threadsafety. I assume that your beans are designed the right way that they aren't doing any business logic in the getters.
Use the application scope for application wide data/constants, such as dropdown lists which are the same for everyone. Use the session scope for client specific data, such as the logged-in user and user preferences (language, etc). Use the view scope for rich ajax-enabled dynamic views (ajaxbased validation, rendering, etc). Use the request scope for simple and non-ajax forms/presentations.

Related

Should objects stored in the sessionScope be thread-safe?

If I'm informed correctly, every request for/from a XPage is processed in a new thread in the JVM on the Domino server.
Hence, all objects stored in the applicationScope which might be modified concurrently by different users should be thread-safe. However, all the articles about thread safety I have read so far never say anything about the necessity of using thread-safe objects in the sessionScope.
A user could, for example, run the same XPage (which modifies a sessionScope object) in two different browser tabs at the same time.
In my opinion, that sessionScope object has to be thread-safe too, or did I get something wrong?
In general, whenever there is more than one thread trying to access the same object and at least one of them tries to modify the state of the object it needs to be threadsafe.
So in this case if two browser tabs try to access same xpage or different xpages but trying to access the same session scope object and at least one of them trying to modify that object, we need to ensure it is threadsafe.
As #Tiny commented regarding the view scoped beans, "According to the JSF specification, AJAX requests made from the same view are queued on the client side. Therefore, the possibility of concurrent access in a view scoped bean is zero. A view scoped bean is not shared across different tabs / windows of the same browser".
Refer to Section 13.3.2 of jsf 2.0 specification.

Observer and JSF ManagedBean

I have a drop down menu from which user selects an item(in my case project he is working on), most of the data displayed by a webpage depends on that selection. So I have couple of view scoped beans that call EJB beans which do database queries that depend on the selected project.
I want to cache most of that data in order to reduce Database queries, but when user changes project it has to notify other beans that change has happened and new data needs to be fetched.
So I had an idea:
projectChangeManager (session scoped managed bean), saves which project is selected, notifies it's subscribers when project changes. Has #PreDestory method implemented where I cleanup observers.
project observers (view scoped managed beans), gets data from EJB based on project selection, has onProjectChange() method which fetches new data from EJB. Has #PreDestory method implemented where projectChangeManager.detach(this) is called to unsubscribe from projectChangeManager.
Is this reasonable approach in JSF? Or is it better not to implement observer pattern but just when user changes project I fetch all cached data and save it in session bean and then in ViewScoped bean I just access that data from SessionScoped bean? Or is there a better way?
To me this looks like overengineering. Initially, I would probably just let every managed bean call the repository/EJB whenever it needs data. Then rely on caching in the persistence layer (JPA/Hibernate/whatever you use).
If this turns out to be a performance problem, you can consider some hand-rolled caching solution.
Even in that case I still don't quite see the advantage of your observer approach. Your second approach (cache in session bean, access from ViewScoped bean) looks simpler and should work just as well.
Finally, if you decide to use caching, consider how to avoid a stale cache. If you cache per session, changes in one session will not be visible in another session. Incidentally, I think this is another reason to leave caching to the persistence layer.

Help me to understand JSF managed bean scope from concurrency view

Can anyone help me to understand the JSF managed bean scope from a concurrency perspective ?
My Understanding:
Once i have a bean scoped in a session scope that's mean : there is only one user can access this managed bean so there is no possibility to concurrency occur.
Also, once i use a bean in a request scope then this bean will be created once a request had initiated
and that bean will be removed once a response returned. (each clients have different copy of this bean)
Also, once i use a bean in a none scope then once the user call the bean it will be created and after finish the call the bean will be removed.
But once i have a bean in an application scope that's mean multiple client can access this bean, so
if i have a critical data it must be protected by synchronization.
All your inputs are highly appreciated.
I think your understanding of the lifespan of each of the scopes is fine.
However, I think your understanding of when to apply synchronization is not good. Whenever you need to synchronize the methods of a bean in a certain scope, then this is usually an indication that the scope of the bean is too wide for the data it holds. You should then put the bean in a more narrow scope or to move the data into another bean in a more narrow scope, so that synchronization is not necessary.
You should put request scoped data (presentational data, synchronous form data, etc) in the request scope. You should put view scoped data (asynchronous form data, rendered attribute conditions, "hidden" values, etc) in the view scope. You should put session scoped data (logged-in user, user preferences, user-specific data, etc) in the session scope. You should put application scoped data (global dropdown list values, configuration settings, etc) in the application scope.

sessionscoped managed bean vs stateful ejb

If I have a #ManagedBean that's #SessionScoped, why would I use a #Stateful EJB? I used it before for shopping carts and maintaining a conversational state, but since a managed bean will be kept during the user session I can store state there, then call SLSB for bussiness logic. Is that correct? If it is, then stateful ejbs will be left for more specific applications such as when you need transactions etc?
Very often stateless session beans can be used for a lot of business problems.
Stateful does not necessarily means only a remote server keeps state, although this is certainly one of the options. A remote Swing client could first send a bunch of data to a stateful session bean, hold on to the stub and then subsequently send some commands that operate on this data. This saves the client from having to send the same (large amount of) data each and every time.
In the remote use case, it indeed somewhat mirrors the usage of the HTTP session when web clients (browsers) are used. The major difference is that the session is per bean here, while with the HTTP session, the session is a scope shared by many beans. Since the HTTP session is based on cookies, and cookies are global for a domain for the entire browser, the HTTP session can not directly support multiple sessions from the same client (e.g. per tab or per window). This is trivial with stateful session beans.
However...
Remote Swing clients talking to remote EJBs are not that common.
In the context you described in your question, you will typically use local EJBs and you will store most state in the HTTP session (be careful with sharing!) and these days in the view scope or conversation scope.
So, finally, when to use stateful session beans in this scenario?
One important use case is the extended persistence context in JPA. Normally with a transaction scoped entity manager, when an entity crosses the transactional boundary of an EJB method call it will be detached. If you want to (optimistically) lock an entity between user interactions, this is undesirable. You'll lose the lock.
With an extended persistence context, the entity remains attached and the locks valid when you return from a call to the stateful session bean. This is very useful for preview functionality to assure that nobody else has made any changes to the entity when you okay after the preview. Or indeed for a shopping cart where you want to assure that for some time the item can't be sold to anyone else while in the cart.

Why shouldn't I use a JSF SessionScoped bean for logic?

I'm developing a java EE web app using JSF with a shopping cart style process, so I want to collect user input over a number of pages and then do something with it.
I was thinking to use an EJB 3 stateful session bean for this, but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
I can set a JSF session scoped bean as a managed property of all of my request beans which means it's injected into them, but unlike a SFSB the JSF managed session scoped bean is tied to the http session and so the same instance is always injected as long as the http session hasn't been invalidated.
So I have multiple tiers
1st tier) JSF managed request scoped beans that deal with presentation, 1 per page.
2nd tier) A JSF managed session scoped bean that has values set in it by the request beans.
3rd tier) A stateless session EJB who executes logic on the data in the JSF session scoped bean.
Why is this so bad?
Alternative option is to use a SFSB but then I have to inject it in my initial request bean and then store it in the http session and grab it back in each subsequent request bean - just seems messy.
Or I could just store everything in the session but this isn't ideal since it involves the use of literal keys and casting . etc .. etc which is error prone. . . and messy!
Any thoughts appreciated I feel like I'm fighting this technology rather than working with it.
Thanks
Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
From the old J2EE 1.3 tutorial:
What Is a Session Bean?
A session bean represents a single
client inside the J2EE server. To
access an application that is deployed
on the server, the client invokes the
session bean's methods. The session
bean performs work for its client,
shielding the client from complexity
by executing business tasks inside the
server.
As its name suggests, a session bean
is similar to an interactive session.
A session bean is not shared--it may
have just one client, in the same way
that an interactive session may have
just one user. Like an interactive
session, a session bean is not
persistent. (That is, its data is not
saved to a database.) When the client
terminates, its session bean appears
to terminate and is no longer
associated with the client.
So it has to do with a "session". But session not necessarily means "HTTP session"
What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Well, first of all, you don't inject a SFSB in stateless component (injection in another SFSB would be ok), you have to do a lookup. Secondly, choosing between HTTP session and SFSB really depends on your application and your needs. From a pure theoretical point of view, the HTTP session should be used for presentation logic state (e.g. where you are in your multi page form) while the SFSB should be used for business logic state. This is nicely explained in the "old" HttpSession v.s. Stateful session beans thread on TSS which also has a nice example where SFSB would make sense:
You may want to use a stateful session
bean to track the state of a
particular transaction. i.e some one
buying a railway ticket.
The web Session tracks the state of
where the user is in the html page
flow. However, if the user then gained
access to the system through a
different channel e.g a wap phone, or
through a call centre you would still
want to know the state of the ticket
buying transaction.
But SFSB are not simple and if you don't have needs justifying their use, my practical advice would be to stick with the HTTP session (especially if all this is new to you). Just in case, see:
Stateless and Stateful Enterprise Java Beans
Stateful EJBs in web application?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
That's not business logic, that's presentation logic.
So I have multiple tiers (...)
No. You have probably a client tier, a presentation tier, a business tier, a data tier. What you're describing looks more like layers (not even sure). See:
Can anybody explain these words: Presentation Tier, Business Tier, Integration Tier in java EE with example?
Spring, Hibernate, Java EE in the 3 Tier architecture
Why is this so bad?
I don't know, I don't know what you're talking about :) But you should probably just gather the multi page form information into a SessionScoped bean and call a Stateless Session Bean (SLSB) at the end of the process.
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
Correction: an EJB session has nothing to do with a HTTP session. In EJB, roughly said, the client is the servlet container and the server is the EJB container (both running in a web/application server). In HTTP, the client is the webbrowser and the server is the web/application server.
Does it make more sense now?
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Use EJB for transactional business tasks. Use a session scoped managed bean to store HTTP session specific data. Neither of both are POJO's by the way. Just Javabeans.
Why shouldn't I use a JSF SessionScoped bean for logic?
If you aren't taking benefit of transactional business tasks and the abstraction EJB provides around it, then just doing it in a simple JSF managed bean is indeed not a bad alternative. That's also the normal approach in basic JSF applications. The actions are however usually to be taken place in a request scoped managed bean wherein the session scoped one is been injected as a #ManagedProperty.
But since you're already using EJB, I'd question if there wasn't a specific reason for using EJB. If that's the business requirement from upper hand, then I'd just stick to it. At least, your session-confusion should now be cleared up.
Just in case you're not aware of this, and as a small contribution to the answers you have, you could indeed anotate a SFSB with #SessionScoped, and CDI will handle the life cycle of the EJB... This would tie an EJB to the Http Session that CDI manages. Just letting you know, because in your question you say:
but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
Also, you could do what you suggest, but it depends on your requirements, until CDI beans get declarative transaction support or extended persistence contexts etc, you'll find yourself writing a lot of boilerplate code that would make your bean less clean. Of course you can also use frameworks like Seam (now moving to DeltaSpike) to enhance certain capabilities of your beans through their extensions.
So I'd say yes, at first glance you may feel it's not necessary to use a stateful EJB, but certain use cases may be better solve through them. If a user adds a product to his cart, and another user adds this same product later, but there is only one unit in stock, who gets it? the one who does the checkout faster? or the one who added it first? What if you want to access your entity manager to persist a kart in case the user decides to randomly close his browser or what if you have transactions that spawn multiple pages and you want every step to be synchronized to the db? (To keep a transaction open for so long is not advisable but maybe there could be a scenario where this is needed?) You could use SLSB but sometimes it's better and cleaner to use a SFSB..

Resources