Is @SessionScoped a good practice?

pedroct92 picture pedroct92 · Mar 6, 2015 · Viewed 9.8k times · Source

I've read about all the differences between the types of scope (@SessionScoped, @ViewScoped, @ApplicationScope and @RequestScope), however, I'm still facing somehow a problem with my application. I have a page-1 with a grid and I send the selected item to a page-2(both page-1 and page-2 are using the same backing bean) to be edited and then persisted. My managed bean was using @RequestScoped from javax.faces.bean.RequestScoped as I've understood it was the ideal scope to use but it didn't work, the bean was being destroyed and the data was getting lost.

Resuming the story, I've changed the annotation to @SessionScoped and it worked but I would like to know if it is a good practice or not? Because I've read that it is not a good practice to use @SessionScoped as the data will be kept alive until the client logout.

Answer

Tarik picture Tarik · Mar 6, 2015

The best practice is to choose the appropriate bean scope (either session scope or another one). The appropriate scope to choose in your case is the @SessionScoped bean, because in case of:

  • RequestScoped: A new bean will be created after each HTTP request-response cycle, which you already encountered when you tried the request scope:

    the bean was being destroyed and the data was getting lost

  • ViewScoped: A new bean will be created once you navigate to another page (page-2 in your case)

    NB: A new bean will be also created each time you interact with the same page using a return value different than void or null.

  • @ApplicationScoped: Simply doesn't make any sense in that example (use it only when you want to share data/state between all users)

I strongly recommand you to take a look at this Q/A: How to choose the right bean scope? which provides detailled explanation on how to properly choose your beans scopes.

Other suggestions could be considered, which depends on your functionnal requirements, and / or application environment:

  1. As you are using the same bean within both pages, you can considere using one single JSF page and make use of the rendered attributes, then you can annotate your bean as @ViewScoped (In that case, don't forget to return void or null in your bean's action method). You may find some examples here: The benefits and pitfalls of @ViewScoped. Or,

  2. You can make use of the new Flash scope concept, an example could be found here: Understand Flash Scope in JSF2. Or,

  3. If your environment already support CDI (Or you can simply add the CDI support), then using @ConversationScoped would be the best choice regarding your case, you may find a good example here: How does JSF 2 ConversationScope work?. Or,

  4. Following Kukeltje's comment, you can use the @ViewAccessScoped or @GroupedConversationScoped provided by Apache DeltaSpike which are both more flexible than the std. @ConversationScoped.