I'm working with JSF technology. I've 2 views and 2 beans. The first View (homepage.xhtml) sets a text parameter in the first Bean (UserBean) which is like so:
@ManagedBean
@SessionScoped
public class UserBean implements Serializable{
private String searchText;
public UserBean(){}
public String search() {
return "searching?faces-redirect=true&text="+searchText;
}
A commandButton in the view submits the search, and calls the UserBean.search(). I have this view in the searching.xhtml, which is a simple DataList component of PrimeFaces showing a list of a user:
<f:metadata>
<f:viewParam name="text" value="#{searchView.searchText}"/>
<f:event type="preRenderView" listener="#{searchView.init()}"></f:event>
</f:metadata>
<h:head>
<title>Search Results</title>
</h:head>
<h:body>
<h:form id="resultsForm">
<p:dataList var="user" value="#{searchView.results}" type="unordered" itemType="none" paginator="true" rows="10" styleClass="paginated">
<f:facet name="header">
Results for #{searchView.searchText}:
</f:facet>
<p:panel>
<p:commandLink update=":resultsForm:userDetail" oncomplete="PF('userDialog').show()" title="user dettagli" styleClass="ui-icon ui-icon-search" style="float:right;margin-right:50px">
<f:setPropertyActionListener value = "#{user}" target="#{searchView.selectedUser}"/>
<h:outputText value="#{user.firstName}, #{user.lastName}" />
</p:commandLink>
<h:outputText value="#{user.firstName} #{user.lastName} (#{user.email})" style="display:inline-block" />
</p:panel>
</p:dataList>
<p:dialog header="User Info" widgetVar="userDialog" modal="true" showEffect="blind" hideEffect="explode" resizable="false">
<p:outputPanel id="userDetail" style="text-align:center;">
<p:panelGrid columns="2" rendered="#{not empty searchView.selectedUser}" columnClasses="label,value">
<h:outputText value="First name:" />
<h:outputText value="#{searchView.selectedUser.firstName}" />
<h:outputText value="Last Name" />
<h:outputText value="#{searchView.selectedUser.lastName}" />
<h:outputText value="Calendar" />
<h:outputText value="#{searchView.selectedUser.visibility}" />
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
<br/>
</h:body>
In the end, I've this backing bean:
@ManagedBean
@ViewScoped
public class SearchView implements Serializable {
private List<User> results;
private User selectedUser;
private String searchText;
@EJB
private SearchingManager sm;
public void init() {
System.out.println("print search text:" + searchText);
results = sm.search(searchText);
}
public SearchView() {
}
public void setSelectedUser(User selectedUser) {
System.out.println("setter of selected user");
this.selectedUser = selectedUser;
}
public User getSelectedUser() {
System.out.println("getter of selected user");
return selectedUser;
}
It works and shows the results of the search correctly but when it opens the page of results I notice this output:
Informazioni: print search text: Mario
Informazioni: getter of selected user
So I'm wondering why that getSelectedUser() is called without selecting any user. Moreover when I select a user it shows an empty dialog and this is the outcome:
Informazioni: getter of selected user
Informazioni: getter of selected user
Informazioni: getter of selected user
Informazioni: print search text: Mario
Informazioni: getter of selected user
So it recalls the init() function why?
And the worst thing is that if we close the Dialog and reopen it, the result is something like that but with
Informazioni: print search text: null
and it stops because of NullPointerException.
I'm spending days searching about this setPropertyActionListener but I can't understand this behavior of the system.