JSF action method not called

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>()); } /*some getters & setters*/ 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

  1. You cannot embed several UIForm components into each other (watch the included files!).

Only one.

  1. There was no validation / conversion error (use h:messages to get them all).

I have h: messages that do not display any errors.

  1. 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.

  1. 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 .

  1. 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.

  1. 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?

+4
source share
1 answer

This can happen if the parent of this <h:form> been processed by an ajax request initiated by another <h:form> in advance. The displayed / updated <h:form> will then lose its view state. This is caused by the JavaScript API error described in JSF issue 790 , which is already fixed for the upcoming JSF 2.2.

At the same time, with JSF 2.0 / 2.1, you need to explicitly specify the client identifier <h:form> in the render attribute (or for PrimeFaces, update ) for the action in another form.

eg.

 <h:commandButton ...> <f:ajax ... render=":listForm" /> </h:commandButton> 

or

 <p:commandButton ... update=":listForm" /> 

Or just make a normal (non-ajax) request instead.

See also:

+5
source

Source: https://habr.com/ru/post/1412386/


All Articles