#Viewscoped bean is not destroyed when navigate to another page - spring

I'm using #Viewscoped beans in a JSF 2.1 project. The strange thing is that when I first get a page the bean is clearly initialized with all the initial parameters. But when I navigate away, to another page, even if I close the browser tab where te app is open the bean does not die. When I go back to the page that use this bean the values are the same that were modified during the utilization of this page. And more, if I open another browser like IE or Chrome, the values are still there too!!
Is behaving like a sessionscoped. Or somekind of inmortal bean , je.
The bean is annotated like this.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#ViewScoped
public class MyBean {
//the rest of the code.
}
Why this is happen? Could be springframework annotation the cause of the problem?

I found the solution. The problem was my spring annotation in the bean. I use #Controller from Spring Framework. This annotation create a Singleton, so my backing bean, even it has #ManagedBean and #ViewScoped, was created only once, and was never destroyed a re-created in every view.
I deleted #Controller and replace #Autowired for #ManagedProperty for the injection and now everything works as expected.
The answer in this a question help to figure out

Define your Bean using this anotations
#ViewScoped
public #Named class MyBean
#PreDestroy works well.

Related

CDI Bean recreated on every <h:inputtext>ajax call [duplicate]

This doesn't seem right. I was doing some cleanup of my code and I just noticed this. Every ajax request is firing the constructor and #PostConstruct of my #ViewScoped bean. Even a simple database pagination is firing it.
I understood that #ViewScoped is longer than #RequestScoped and that it shouldn't be reconstructed on every request. Only after a complete page reload by GET.
In other words, your #ViewScoped bean behaves like a #RequestScoped bean. It's been recreated from scratch on every postback request. There are many possible causes for this, most of which boils down that the associated JSF view is not available anymore in the JSF state which in turn is by default associated with the HTTP session.
Provided that you can assure that the HTTP session itself is not the root cause of the problem, i.e. when #SessionScoped works absolutely fine, then walk through the below list of possible causes. Otherwise, if the HTTP session itself is also trashed and recreated on every single request, then you need to take a step back and look at session cookie and server configuration. Any cause related to a broken HTTP session is at least beyond the context of JSF.
You're using Mojarra 2.1.17 or older, and the view contains EL expressions which bind a view scoped bean property to a tag attribute which is evaluated during view build time. Examples are JSTL <c:if>, <c:forEach>, etc or JSF <ui:include>, <x:someComponent id="#{...}", <x:someComponent binding="#{...}">, etc. This is caused by a bug in Mojarra (issue 1496). See also Why does #PostConstruct callback fire every time even though bean is #ViewScoped? JSF
This is already fixed in Mojarra version 2.1.18. If you can't upgrade to a newer version, the workaround is to disable partial state saving as below in web.xml, see also JSTL in JSF2 Facelets... makes sense?
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
Or when you want to target a specific set of JSF views only:
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/foo.xhtml;/bar.xhtml;/folder/baz.xhtml</param-value>
</context-param>
Important to mention is that binding the value of JSF component's id or binding attribute to a view scoped bean property is a bad practice. Those should really be bound to a request scoped bean property, or an alternative should be sought. See also How does the 'binding' attribute work in JSF? When and how should it be used?
You're using Mojarra 2.2.0, only that version has a (yet unknown) bug in maintaining the view scope which is already fixed in 2.2.1, see also issue 2916. Solution is to upgrade to a newer version.
The #ViewScoped annotation is imported from the wrong package. JSF offers two #ViewScoped annotations, one from javax.faces.bean package for JSF managed beans annotated with #ManagedBean, and another one from javax.faces.view package for CDI managed beans annotated with #Named. When the bean scope annotation does not match the bean management annotation, then the actual bean scope will become the bean management framework's default scope, which is #RequestScoped in JSF managed beans and #Dependent in CDI managed beans.
You need to ensure that you have either of the following constructs and don't mix them, see also #ViewScoped bean recreated on every postback request when using JSF 2.2.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class CorrectJSFViewScopedBean implements Serializable {
import javax.inject.Named;
import javax.faces.view.ViewScoped;
#Named
#ViewScoped
public class CorrectCDIViewScopedBean implements Serializable {
The view is (accidentally?) marked transient via <f:view transient="true">. This basically turns on "stateless JSF", which is new since Mojarra 2.1.19. Hereby the JSF view simply won't be saved in the JSF state at all and logical consequence is that all referenced view scoped beans can't be associated with the JSF view anymore. See also What is the usefulness of statelessness in JSF?
The web application is configured with com.sun.faces.enableRestoreView11Compatibility context param set to true in an incorrect attempt to "avoid" ViewExpiredException. With this context param, the ViewExpiredException will never be thrown, but the view (and all associated view scoped beans) will just be recreated from scratch. However, if that happens on every request, then this approach actually hides another problem: the views expire way too soon. This indicates a possible problem in maintaining the JSF view states and/or the HTTP session. How to solve/configure that properly, head to javax.faces.application.ViewExpiredException: View could not be restored.
The web application's runtime classpath is polluted with multiple different versioned JSF API or impl related classes. This causes a corruption/mismatch in the identifiers/markers for the JSF view state. You need to make sure you don't have multiple JSF API JAR files in webapp's /WEB-INF/lib. In case you're using Maven, make carefully sure that you mark server-provided libraries as <scope>provided</scope>. See also "Installing JSF" section in our JSF wiki page and the answer to this related question: How to properly install and configure JSF libraries via Maven?.
When you're using PrimeFaces <p:dialog>, then make sure that the <p:dialog> has its own <h:form> and that it is not nested in another <h:form>. See also p:fileUpload inside p:dialog losing #ViewScoped values.
When you're combining PrimeFaces FileUploadFilter with PrettyFaces, then make sure that the FileUploadFilter also runs on PrettyFaces-rewritten/forwarded requests. See also ViewScoped bean rebuilt when FileUploadListener called using PrettyFaces and How to use PrimeFaces p:fileUpload? Listener method is never invoked or UploadedFile is null / throws an error / not usable.
When you're using PrettyFaces, a badly configured rewrite rule which redirects CSS/JS/image resources to a JSF page tied to a #ViewScoped bean will also give misleading behavior. See also CDI ViewScope & PrettyFaces: Multiple calls to #PostConstruct (JSF 2.2).

why jsf save state of bean in different browsers [duplicate]

I have a #RequestScoped bean with a List property.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
private List list;
// getters and setters
}
This property is linked to a datatable:
<ice:dataTable value="#{myBean.list}" ..other stuff.. />
The List is dynamically filled with no problem, and the datatable is displayed with no problems. But if, I navigate to another page, and then go back to the initial page the datatable is still with the data of the initial request. It shouldn't be empty again? If the bean is request scoped it should be destroyed after the request, and I should get and empty datatable as the beginning.
Even more strange is that if I open the page in one browser (like Firefox), fill the datatable with a request, then I open another browser (like Chrome) and go to the datatable page, it is filled with the data from previous request from another browser! I think the bean is behaving like an application one.
Any ideas?
Update 1: The class is not static neither its variables. Also, I disable tomcat cache, but still not working.
Update 2: I think probably found the problem. My backing beans are annotated with #Controller from Spring. I use this annotation because then use #Autowired to bind services. Could be this is creating a singleton and that why is not being created and destroyed with every request? I think pretty sure the problem is in the mix of Spring and JSF2 annotations.
You shouldn't manage a single bean by multiple different bean management frameworks like JSF, CDI and Spring. Choose the one or the other. When managing the bean by for example Spring's #Controller, all bean management related annotations of other frameworks like JSF's #ManagedBean and CDI's #Named are ignored.
I don't do Spring and I have no idea why you're using it instead of the standard Java EE 6 API, but the symptoms and documentation indicates that the scope of such a Spring bean indeed defaults to the application scope. You need to specify the bean scope by Spring #Scope annotation. You would also like to remove the JSF bean management annotations since they have no value anymore anyway and would only confuse the developer/maintainer.
#Controller
#Scope("request")
public class MyBean implements Serializable {
// ...
}
Alternatively, you can also get rid of Spring #Controller annotation and stick to JSF #ManagedBean. You can use #ManagedProperty instead of #Autowired to inject another #ManagedBean instance or even a Spring managed bean (if you have Spring Faces EL resolver configured), or the Java EE standard #EJB to inject an #Stateless or #Stateful instance.
E.g.
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
#EJB
private SomeService service;
// ...
}
See also:
Spring JSF integration: how to inject a Spring component/service in JSF managed bean?

Data from #RequestScoped bean is shared in different browsers

I have a #RequestScoped bean with a List property.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import org.springframework.stereotype.Controller;
#Controller
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
private List list;
// getters and setters
}
This property is linked to a datatable:
<ice:dataTable value="#{myBean.list}" ..other stuff.. />
The List is dynamically filled with no problem, and the datatable is displayed with no problems. But if, I navigate to another page, and then go back to the initial page the datatable is still with the data of the initial request. It shouldn't be empty again? If the bean is request scoped it should be destroyed after the request, and I should get and empty datatable as the beginning.
Even more strange is that if I open the page in one browser (like Firefox), fill the datatable with a request, then I open another browser (like Chrome) and go to the datatable page, it is filled with the data from previous request from another browser! I think the bean is behaving like an application one.
Any ideas?
Update 1: The class is not static neither its variables. Also, I disable tomcat cache, but still not working.
Update 2: I think probably found the problem. My backing beans are annotated with #Controller from Spring. I use this annotation because then use #Autowired to bind services. Could be this is creating a singleton and that why is not being created and destroyed with every request? I think pretty sure the problem is in the mix of Spring and JSF2 annotations.
You shouldn't manage a single bean by multiple different bean management frameworks like JSF, CDI and Spring. Choose the one or the other. When managing the bean by for example Spring's #Controller, all bean management related annotations of other frameworks like JSF's #ManagedBean and CDI's #Named are ignored.
I don't do Spring and I have no idea why you're using it instead of the standard Java EE 6 API, but the symptoms and documentation indicates that the scope of such a Spring bean indeed defaults to the application scope. You need to specify the bean scope by Spring #Scope annotation. You would also like to remove the JSF bean management annotations since they have no value anymore anyway and would only confuse the developer/maintainer.
#Controller
#Scope("request")
public class MyBean implements Serializable {
// ...
}
Alternatively, you can also get rid of Spring #Controller annotation and stick to JSF #ManagedBean. You can use #ManagedProperty instead of #Autowired to inject another #ManagedBean instance or even a Spring managed bean (if you have Spring Faces EL resolver configured), or the Java EE standard #EJB to inject an #Stateless or #Stateful instance.
E.g.
#ManagedBean
#RequestScoped
public class MyBean implements Serializable {
#EJB
private SomeService service;
// ...
}
See also:
Spring JSF integration: how to inject a Spring component/service in JSF managed bean?

CDI session scoped bean is created only one time also if the user access from two different browser

i have a strange behaviour i'm seeing that if the user access to session bean from two different browser, the istance of session bean is the same. In my opinion this is an unespected behaviour.
Someone have solved the same problem?
I'm using Jsf 2.0, Spring 3.0.5, Hibernate and like WebServer Glassfish.
Thank you in advance.
Update
import model.entity.Utente;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
/**
*
* #author
*/
#Named
#SessionScoped
public class SessionBean implements Serializable {
this is how i declare CDI session bean
I guess the bean is managed by Spring not by CDI. (If you want to use CDI with Spring you need to do a lot of work, only using javax.inject.Named is not enougth.)
Spring knows javax.inject.Named but not javax.enterprise.context.SessionScoped. To make a Spring Bean Session scoped, you need #org.springframework.context.annotation.Scope("session").
#see also: Spring Reference Chapter 3.5.4 Request, session, and global session scopes

How to inject a Spring 3 Bean into a JSF 2 Converter

I am trying to #javax.naming.Inject a Spring 3 Bean called WtvrBean into a JSF 2 #FacesConverter.
Both the Bean and the Converter are on the same package. And, in my spring's applicationContext.xml, I am scanning this package:
<context:component-scan base-package="my-package" />
But this is not working. For sure, the JSF 2 internal class that uses the converter is
definitely not in my-package.
For instance, if I remove the #ManagedBean from a JSF 2 ManagedBean, and replace it to #org.springframework.stereotype.Component or #Controller, the WtvrBean can be #Injected on this ManagedBean, by using Spring WebFlow.
Well, as far as I know, there is no such thing as a #Converter stereotype in Spring.
I know I can use
FacesContextUtils.getWebApplicationContext(context).getBean("WtvrBean")
But, with that approach, the coupling between the web app and the spring is getting more tight. (annotations are metadata, and are not even considered dependency by some authors).
I am using FacesContextUtils so far, if there is no better solution.
Any ideas?
If you want to inject beans into instances of a class, these instances have to be spring-managed. I.e. spring has to instantiate them. And this is not happening, so - no, you can't inject there.
But this is because you register the converter within jsf. You can skip that:
#Component("myConverter")
public class MyConverter implements Converter { .. }
And then, if you are using the spring <el-resolver>:
converter="#{myConverter}"
So that will do it. It has worked for me.
(A workaround worth mentioning is that you can do it by using aspectj weaving and #Configurable, but I'd prefer your FacesContextUtils approach. The weaving modifies classes so that they become spring managed even if they are not instantiated by spring.)
#FacesConverter(value = "examTypeConverter")
#Named
Simple answer.
hey i was facing the same problem that spring beans are not getting injected in the JSF Converter.
then by googling about it i found the answers that after JSF 2.2 we can make converters as jsf managed bean. and then we can inject the spring dependency.
it solved my problem.
#ManagedBean
#RequestScoped
public class CustomerByName implements Converter {
#ManagedProperty(value = "#{customerDao}")
private CustomerDao customerDao;
and in your jsf page use it like a managed bean
converter="#{customerByName}"
Add #Scope annotation (eg with "request" parameter) to your managed bean.
#ManagedBean
#Scope("request")
public class MyBean {
....
}

Resources