The situation is that I have a ViewScoped page that uses ui:repeat for laying out some components. I also on this page have some h:commandLinks that have action method specified. The action method performs some conditional logic to determine what navigation outcome to return. Upon returning an outcome and including "faces-redirect=true" to perform a redirect, the current view's bean is reinstantiated before the redirect occurs.
Removing the ui:repeat causes the issue to stop, I know longer see the constructor of the bean being invoked. Also, I cannot use h:links in this case, because I want to be able to calculate the outcome at the moment the link is clicked.
Is this a known bug with ui:repeat? I have searched around and could not find why this is happening.
Here is some sample code that I can reproduce this with using Mojarra JSF 2.1.6:
example.xhtml
<h:form>
<h:outputText value="Bean property value: #{exampleBean.property}"/>
<ui:repeat value="#{exampleBean.list}" var="item">
<h:outputText value="#{item}"/>
</ui:repeat>
<br/><h:commandLink value="Action" action="#{exampleBean.someAction()}"/>
<br/><h:commandLink value="Action w/Redirect" action="#{exampleBean.someRedirectAction()}"/>
</h:form>
ExampleBean.java
@ManagedBean(name="exampleBean")
@ViewScoped
public class ExampleBean {
private String property;
private List<String> list;
public ExampleBean() {
System.err.println("Constructor invoked");
list = new ArrayList<String>();
list.add("list item 1");
list.add("list item 2");
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public String someAction() {
System.err.println("someAction() invoked");
if (calculateSomeCondition()) {
return "otherView1";
} else {
return "otherView2";
}
}
public String someRedirectAction() {
System.err.println("someRedirectAction() invoked");
if (calculateSomeCondition()) {
return "otherView1?faces-redirect=true";
} else {
return "otherView2?faces-redirect=true";
}
}
private boolean calculateSomeCondition() {
// some logic to calc true/false
}
}
Note that otherView1.xhtml and otherView2.xhtml are simple files sitting in the same directory as example.xhtml.
The output seen in the log upon loading the page and clicking the "Action" link:
Constructor invoked
someAction() invoked
The output seen in the log upon loading the page and clicking the "Action w/Redirect" link:
Constructor invoked
someRedirectAction() invoked
Constructor invoked