Multiple browser tabs or windows with the same ViewScoped bean class
Using Payara Server 4.1.2.174 with mojarra 2.2.15.
I have a simple Named Bean with scope javax.faces.view.ViewScoped.
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String action()
{
logger.log(Level.SEVERE, "{0}.action()", this);
logger.log(Level.SEVERE,"====================");
logger.log(Level.SEVERE, "name: {0}", getName());
logger.log(Level.SEVERE,"====================");
return "submit";
}
@PostConstruct
private void init()
{
logger.log(Level.SEVERE, "{0}.init()", this);
}
So I have a simple index.xhtml page with form.
<h:form>
<h:inputText value="#{simpleBean.name}"></h:inputText>
<h:link value="To submit" outcome="submit"/>
<h:commandButton value="Welcome Me" action="#{simpleBean.action()}"/>
</h:form>
I can open index.xhtml in two different browser tabs or windows. So, I have the following log:
Severe: [email protected]() Finest: Handling PostConstructViewMapEvent Finest: Handling PreDestroyViewMapEvent Finest: Destroying @ViewScoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@2adafd68} Severe: [email protected]() Finest: Handling PostConstructViewMapEvent Finest: Handling PreDestroyViewMapEvent Finest: Destroying @ViewScoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@49a86248}
As we can see there are two different instances of SimpleBean. After that I submit the form of the first tab.
Severe: [email protected]() Severe: ==================== Severe: name: First tab Severe: ==================== Finest: Handling PreDestroyViewMapEvent Finest: Destroying @ViewScoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@2adafd68} Finest: Handling PreDestroyViewMapEvent Finest: Destroying @ViewScoped beans from view map: {}
If I try to submit form of the second tab the stored earlier instance of SimpleBean (solvo.ee.beans.SimpleBean@49a86248) won't be used, instead the ViewScopeContextManager will create a new instance of SimpleBean class, as we can see in log:
Severe: [email protected]() Severe: [email protected]() Severe: ==================== Severe: name: Second tab Severe: ==================== Finest: Handling PreDestroyViewMapEvent Finest: Destroying @ViewScoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean@4797f115} Finest: Handling PreDestroyViewMapEvent Finest: Destroying @ViewScoped beans from view map: {}
I have checked the code of the com.sun.faces.application.view.ViewScopeContextManager.copyViewScopeContextsFromSession method and as I understand this behavior is normal. However If i store request parameters or another important data in my bean I will loose it because the instance will be lost after submitting the first form.
Is there a solution to keep bean associated with the second tab primarily (in my example solvo.ee.beans.SimpleBean@49a86248)?
The further researches have shown that this bug appeared since 2.2.13 version. The correct behaviour was broken by commit c73283a6770191ff4f47c24234fa93d92dfdf0e0.
Thanks for this report, I haven't looked at this is detail yet but if its indeed the case it sounds serious enough. Hopefully I'll be able to find the time to look into this soon. Thanks again!