I have a JSF view with a Primefaces data table and the command line button is like a pair:
<p:messages id="statusMessages" showDetail="true" /> <h:form id="listForm"> <p:panel header="Wellsite List"> <br /> <h:outputLabel value="Welcome, #{wellsiteController.loggedUser.login}" /> <br /> <br /> <p:dataTable id="dataTable" var="wellsite" value="#{wellsiteController.wellsiteDataTableModel}" paginator="true" rows="10" selection="#{wellsiteController.wellsite}"> <p:column selectionMode="single" style="width:18px" id="radioSelect" /> <p:column sortBy="#{wellsite.reference}" headerText="Wellsite ID"> <h:outputText value="#{wellsite.reference}" /> </p:column> <p:column headerText="Allowed Groups"> <h:outputText value="#{wellsite.allowedGroups.toString()}" /> </p:column> <f:facet name="footer"> <h:panelGrid columns="3"> <p:commandButton id="addWellsite" value="Add New Wellsite" icon="ui-icon-flag" ajax="false" action="#{wellsiteController.showAddWellsite}"/> <p:commandButton id="editWellsite" value="Edit Selected Wellsite" icon="ui-icon-wrench" ajax="false" action="#{wellsiteController.showEditWellsite}"/> <p:commandButton id="deleteWellsiteButton" value="Remove Selected Wellsite" icon="ui-icon-trash" onclick="confirmation.show()" type="button"/> </h:panelGrid> </f:facet> </p:dataTable> <p:spacer height="20" /> </p:panel> <p:confirmDialog id="confirmDialog" message="Are you sure you want to remove the selected Wellsite along with all it data?" header="Confirmation" severity="alert" widgetVar="confirmation"> <p:commandButton id="confirm" value="Yes" ajax="false" oncomplete="confirmation.hide()" action="#{wellsiteController.deleteWellsite}" /> <p:commandButton id="decline" value="Cancel" onclick="confirmation.hide()" type="button" /> </p:confirmDialog> </h:form>
And here is the controller:
@ManagedBean(name = "wellsiteController") @RequestScoped public class WellsiteController implements Serializable { private static final long serialVersionUID = 1L; @ManagedProperty("#{wellsiteDao}") private WellsiteDao wellsiteDao; @ManagedProperty("#{userDao}") private UserDao userDao; @ManagedProperty("#{groupDao}") private GroupDao groupDao; @ManagedProperty("#{userController.loggedUser}") private UserEnt loggedUser; private WellsiteEnt wellsite; private List<WellsiteEnt> wellsiteList; DualListModel<GroupEnt> pickGroupsModel; public WellsiteController(){ } @PostConstruct public void build(){ wellsite = new WellsiteEnt(); wellsite.setAllowedGroups(new ArrayList<GroupEnt>()); } public WellsiteDataTableModel getWellsiteDataTableModel(){ return new WellsiteDataTableModel(getWellsiteList()); } public void setPickGroupsModel(DualListModel<GroupEnt> model){ pickGroupsModel = model; } public DualListModel<GroupEnt> getPickGroupsModel() { if(pickGroupsModel == null){ List<GroupEnt> allGroups = groupDao.getAll(); List<GroupEnt> currentGroups = wellsite.getAllowedGroups(); for(GroupEnt g : currentGroups){ allGroups.remove(g); } pickGroupsModel = new DualListModel<GroupEnt>(allGroups, currentGroups); } return pickGroupsModel; } public String listWellsites(){ getWellsiteList(); return "listWellsites"; } public String showAddWellsite(){ FacesContext context = FacesContext.getCurrentInstance(); setWellsite(new WellsiteEnt()); wellsite.setAllowedGroups(new ArrayList<GroupEnt>()); pickGroupsModel = null; context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Fields annotated with a ' * ' are mandatory","")); return "addWellsite"; } public String addWellsite(){ FacesContext context = FacesContext.getCurrentInstance(); wellsite.setDate(new Date()); wellsite.setLastUpdate(wellsite.getDate()); try { wellsiteDao.addWell(wellsite); for(GroupEnt g : pickGroupsModel.getTarget()){ GroupEnt group = groupDao.getOne(g.getGroupId()); group.getGroupWellsites().add(wellsite); groupDao.update(group); } return listWellsites(); } catch (Exception ex) { Logger.getLogger(WellsiteController.class.getName()).log(Level.SEVERE, null, ex); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(),"")); return null; } } }
This view is displayed correctly. Data items and buttons look great. The problem is that when I first click the addWellsite command, nothing happens. The page seems to be refreshing. If I click on it again as soon as an exception occurs:
java.lang.NumberFormatException: For input string: "null"
Using the debugger, I found out that the "addWellsite" action is NOT called for the first time, and therefore the result is not generated (thus updating the page).
The exception is probably due to the lack of initialization in the current or target views (since both views are displayed from action methods that were not called in the page refresh)
Question: WHY is the action method not called for the first time?
How from this answer :
Whenever the UICommand
component cannot trigger a related action, check the following:
UICommand
components must be placed inside a UIForm
component (for example, h:form
).
I have h: form
- You cannot embed several
UIForm
components into each other (watch the included files!).
Only one.
- There was no validation / conversion error (use
h:messages
to get them all).
I have h: messages that do not display any errors.
- If the
UICommand
components UICommand
located inside the UIData
component, make sure that the exact same DataModel
(the object behind the UIData
value
attribute) is stored.
CommandButton is inside a dataTable, but the target view does not require a dataModel. As my controller code shows, an object is built as the view tries to retrieve it. The following query does not use this dataTable so that I no longer process it.
- The attributes of the
rendered
and disabled
components and all parent components should not be evaluated to false
during the request phase of the request.
No rendered
or disbled
.
- Ensure that no
PhaseListener
or any EventListener
in the request and response chain has changed the JSF life cycle to skip the call phase.
The phase shifter is defined.
- Make sure that no
Filter
or Servlet
in the same request-response chain has blocked the FacesServlet
request FacesServlet
any way.
No other servlet is specified. I donโt even know what a Filter is.
WHY is the action method not called the first time?