@Predestroy on @Viewscoped

Asked

Viewed 856 times

4

I noticed that @Predestroy in @Viewscoped scoped Beans is only called if the session that was active expires or if I force a page redirect (?faces-redirect=true). Without these conditions, the bean with this scope is never destroyed, and every time I enter the page the bean is created again.

1 - It is problematic that the bean will never be destroyed and will always be created every time the page is accessed?

2 - It is valid to force bean destruction using redirect?

3 - What is the benefit of @Viewscoped over @Sessionscoped in this context?

  • There is a bug regarding the behavior you mentioned, the @preDestroy is only called when the session expires, generating memory Leak. They said it was fixed in version 2.2 of the specification in 2012 (https://java.net/jira/browse/JAVASERVACES_SPEC_PUBLIC-905). I found Issue in the implementation of Jboss Wildfly (https://issues.jboss.org/browse/WFLY-785) and it has not been solved yet. I think it depends on each Container, try searching if your container fixed this bug.

  • In the version of Glassfish I am using (3.1) this supposed bug persists. I wonder if it is harmful to the application to let you create several Bens in memory without destroying them, as is the case with @Viewscoped. One solution I found was to use redirect whenever browsing another page, hence yes the bean is destroyed.

  • As I mentioned, there will be the memory problem Leak, let alone statefull for your bean, worse. The solution that gave is not bad, I’m just not sure of the side effects.

2 answers

3


A bean of the kind @Viewscoped will be active while requests are made to the same page. When you make a request to another page or another bean the scope is clean.

When working with JSF it is very important to know the life cycles well. I don’t quite understand when you use the term "force" destruction, but I think it would be more appropriate to use a @Requestscope, which will be created at the beginning of a request and destroyed at the end of the request.

There is no advantage between the @Viewscoped about the @Sessionscoped because both are used for different purposes. A bean @Sessionscoped is instantiated once, which is when a user starts a session in your app and destroyed when the session is ended.

EDIT As I mentioned in some comments on other answers to this question, it is very important to separate the Managedbeans by "concept" (Ex.: Personal, Address cover, etc...) so that the Viewscope meets you correctly. If you need to access other Beacons, remember that it is possible to inject one Managedbean into another, this way you will not kill your main bean.

  • If I have a menu with two items, one of the items I direct to page1 (action="page1") and the other item I direct to page2 (action="page2"). If I enter page 1 and soon after I enter page 2, the bean created on page 1 is not destroyed. Your statement about the bean staying active until you navigate to another page is not 100% true.

  • @Electus edited the answer to be clearer. But Managedbeam will only be destroyed if you post to another view.

  • Excuse the ignorance, but could you give me an example in practice when you say "the scope will only be cleared in the case where the request for another view is made through a POST"? I’ve been studying more in depth JSF for a short time and there are things I may not have assimilated yet. Another thing: when you say to use @Requestscoped, I believe it will depend on the situation. In the project that I am involved uses a lot AJAX and Dialogs as a way to simulate a desktop environment. With request scope "things" do not work properly.

  • @Electus The statement caused more confusion than it helped, until I withdrew it from the reply. There’s not much to talk about life cycles because they’re very well documented. What I suggest to you is to use the maximum of JSF and components. The implementation of JSF also makes a difference, prefer Mojarra. I suggested you request Scope just in case you need to clear your bean at each access.

  • Edgar, thank you for your time. There really is a bug (at least I think it is a bug) in relation to @Viewscoped, because it is not destroyed when I navigate to another JSF page, only if I force a redirect to another page (I have done several tests and can say without fear). Maybe the problem is related to the application server I use (Glassfish 3.1) and not to the JSF itself. Thanks again.

2

1 - It is problematic that the bean will never be destroyed and will always be created every time the page is accessed?

Things like this are the reason I don’t recommend JSF for any new project.

Yes, there is considerable progress in API and implementations, but this has not been accompanied by a solution to recurring JSF problems.

2 - It is valid to force bean destruction using redirect?

Everything is valid as long as it fulfills the necessary function without causing unwanted side effects.

Unfortunately, when we use a framework that abstracts a lot the operation of a web system, we often have to use tricks to be able to do the tuning necessary.

On a system I worked on, which used JSF 1.1, I had to implement a session cleaning routine every time a menu was accessed. This was because the system was legacy and the developers had a habit of putting everything in session scope. There was no possibility of refactoring the system.

Basically, "Interceptei" each call to a menu option to identify when the user output from one screen to another. So I would scroll through the session map and remove entries, except for some that were actually "global". Differentiation was made based on prefixes in attribute names.

3 - What is the benefit of @Viewscoped over @Sessionscoped in this context?

The @ViewScoped tries to automate the scenario described above. It works well on a screen that always uses Ajax to perform the operations.

However, a simple CRUD with search, inclusion, alteration and exclusion screens cannot make use of this resource. To begin with, if the user does a search and changes an element, all filters are lost.

In the end you realize that using the session improves usability in the sense that some values are required to remain stored for the user. On the other hand, using the session also causes problems because the user can open multiple tabs and windows and the behavior of the system ends up becoming unpredictable.

And, contrary to what it may seem, the scope of View generates the same thing. If the user opens several tabs with the same page, one of them will change the status of the others. Some people think that the View Scope solves JSF problems, but it only minimizes some and actually causes others.

As a consequence you end up with strange usage requirements at least as: the system cannot be used in more than one window at the same time.

At the end of the day, the conclusion is that reasonable usability is only achieved with the scope of the request (Request Scope). But then you completely lose the advantage of a framework Component based like JSF. Including several components (think about dataTable of Primefaces) no longer function properly with the scope of request. And even what works ends up giving so much work as if you were doing things "in hand".

And, with all this, it was concluded that from the beginning a framework should have been used action based.

  • "However, a simple CRUD with search, inclusion, alteration and exclusion screens cannot make use of this resource. To begin with, if the user does a search and changes an element, all filters are lost." This statement is only true when the developer doesn’t know how to work with the technology. I’ve been working with JSF for years and I can tell you this.

  • @Edgarmunizberlinck If CRUD is not Ajax and the scope is View, the system will lose the registration information. Solutions are to keep the filter in session scope or else store manually. What you usually do?

  • The bean will only be destroyed if you access another page by POST or access another Managedbean. Usually I have a bean Managed by "concept".

  • @Edgarmunizberlinck I understand, but then you can’t, for example, have a separate change or include screen that does POST. What if the system has a sub-server? Or a popup with search filter?

  • 2

    You can use the same bean or you can inject other Beans as well, depending on the problem. The viewscope works very well, just use it knowing how it works. Of course there is no silver bullet.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.