title: JSF/Primefaces Action Listener not invoked from p:commandButton
body: <p>I am migrating an JSP/Servlets website to JSF and am having difficulty in implementing some of the more interesting abilities of JSF.  The current problem that I have attempted to resolve for several days is deleting one or more rows from a <code>&lt;p:dataTable&gt;</code>.  The following code snippet defines the table:</p>
  
  <pre><code>&lt;ui:composition template="/templates/RescueDBAdminTemplate.xhtml" ... &gt; 
  &lt;ui:define name="body"&gt;
      &lt;div id="mainContent"&gt;
          &lt;h1&gt; Pet Information Edit &lt;/h1&gt;
  
          &lt;p&gt;
             This page allows the detailed information for an animal to be inserted or edited.
          &lt;/p&gt;
          &lt;br /&gt;
  
          &lt;!--
          ~~~~ The first row contains the AIF number, and two optional hyperlinks to the History and Cage Card
          ~~~~ pages.  Since we have at most three entries, and a layout of 4 columns, we will need a sub-table
          ~~~~ to evenly space out these objects.
          ~~~~ --&gt;
          &lt;table class="w100pct"&gt;
             &lt;tr&gt;
                &lt;!--
                ~~~~ Display the AIF_NO for the animal at the top of the page.  For Reference Only.
                ~~~~ --&gt;
                &lt;td class="label" align="left" &gt;
                   AIF Number: #{animals.aifNo}
                &lt;/td&gt;
  
                &lt;td align="center"&gt; &lt;a href="/${context}/Protected/AifServlet?COMMAND=HISTORY&amp;amp;AIF_NO=${aifBean.aifNo}" target="window"&gt; Display History   &lt;/a&gt; &lt;/td&gt;
                &lt;td align="right"&gt;  &lt;a href="/${context}/Protected/AifServlet?COMMAND=CARD&amp;amp;AIF_NO=${aifBean.aifNo}"    target="window"&gt; Display Cage Card &lt;/a&gt; &lt;/td&gt;
             &lt;/tr&gt;
          &lt;/table&gt;
  
          &lt;p:accordionPanel id="profile" multiple="true" activeIndex="0,1,2,3,4,5,6,7"&gt;
              &lt;p:tab title="Cage Card Information"&gt;
                  &lt;h:form id="cageCardForm"&gt;
                      &lt;p:panelGrid styleClass="rdbGrid w100pct"&gt;
                          &lt;p:row&gt;
                              &lt;p:column styleClass="block"&gt; Child Friendly: &lt;/p:column&gt;
                              &lt;p:column&gt;
                                  &lt;p:selectOneMenu id="childFriendly" value="#{animals.isChildFriendly}"&gt;
                                      &lt;f:selectItem itemValue="Y" itemLabel="Yes"     /&gt;
                                      &lt;f:selectItem itemValue="N" itemLabel="No"      /&gt;
                                      &lt;f:selectItem itemValue="U" itemLabel="Unknown" /&gt;
                                      &lt;f:selectItem itemValue="O" itemLabel="Older Children Only" /&gt;
                                  &lt;/p:selectOneMenu&gt;
                              &lt;/p:column&gt;
                              &lt;p:column styleClass="block"&gt; Dog Friendly:   &lt;/p:column&gt;
                              &lt;p:column&gt;
                                  &lt;p:selectOneMenu id="dogFriendly" value="#{animals.isDogFriendly}"&gt;
                                      &lt;f:selectItem itemValue="Y" itemLabel="Yes"       /&gt;
                                      &lt;f:selectItem itemValue="N" itemLabel="No"        /&gt;
                                      &lt;f:selectItem itemValue="U" itemLabel="Unknown"   /&gt;
                                      &lt;f:selectItem itemValue="T" itemLabel="Tolerates" /&gt;
                                      &lt;f:selectItem itemValue="S" itemLabel="Some"      /&gt;
                                  &lt;/p:selectOneMenu&gt;
                              &lt;/p:column&gt;
                          &lt;/p:row&gt;
                          &lt;p:row&gt;
                              &lt;p:column styleClass="block"&gt; Cat Friendly:   &lt;/p:column&gt;
                              &lt;p:column&gt;
                                  &lt;p:selectOneMenu id="catFriendly" value="#{animals.isCatFriendly}"&gt;
                                      &lt;f:selectItem itemValue="Y" itemLabel="Yes"       /&gt;
                                      &lt;f:selectItem itemValue="N" itemLabel="No"        /&gt;
                                      &lt;f:selectItem itemValue="U" itemLabel="Unknown"   /&gt;
                                      &lt;f:selectItem itemValue="T" itemLabel="Tolerates" /&gt;
                                      &lt;f:selectItem itemValue="S" itemLabel="Some"      /&gt;
                                  &lt;/p:selectOneMenu&gt;
                              &lt;/p:column&gt;
                              &lt;p:column styleClass="block"&gt; Housebroken:    &lt;/p:column&gt;
                              &lt;p:column&gt;
                                  &lt;p:selectOneMenu id="housebroken" value="#{animals.isHousebroken}"&gt;
                                      &lt;f:selectItem itemValue="Y" itemLabel="Yes"       /&gt;
                                      &lt;f:selectItem itemValue="N" itemLabel="No"        /&gt;
                                      &lt;f:selectItem itemValue="U" itemLabel="Unknown"   /&gt;
                                  &lt;/p:selectOneMenu&gt;
                              &lt;/p:column&gt;
                          &lt;/p:row&gt;
  
                          &lt;p:row&gt;
                              &lt;p:column styleClass="block" style="text-align:top;"&gt; Cage Card Comments:  &lt;/p:column&gt;
                              &lt;p:column&gt; &lt;p:inputTextarea name="previousOwner" rows="11" cols="40" value="#{animals.cageCardComment}" /&gt; &lt;/p:column&gt;
                              &lt;p:column styleClass="block" style="text-align:top;"&gt; Lifestyle Needs:  &lt;/p:column&gt;
                              &lt;p:column&gt; &lt;p:inputTextarea name="reasonObtained" rows="11" cols="40" value="#{animals.lifestyleNeeds}" /&gt; &lt;/p:column&gt;
                          &lt;/p:row&gt;
                      &lt;/p:panelGrid&gt;
                  &lt;/h:form&gt;
              &lt;/p:tab&gt;
              &lt;p:tab title="Fees and Expenditures"&gt;
                  &lt;h:form id="feesForm"&gt;
                      &lt;p:panelGrid styleClass="rdbGrid w100pct"&gt;
                         &lt;p:row&gt;
                             &lt;p:column styleClass="block"&gt; Adoption Fee:  &lt;/p:column&gt;
                          &lt;p:column&gt;
                              &lt;p:inputText size="16" value="#{animals.adoptionFee}" maxlength="64" /&gt;
                          &lt;/p:column&gt;
                          &lt;p:column styleClass="block"&gt; Normal Costs:  &lt;/p:column&gt;
                          &lt;p:column&gt;
                              &lt;p:inputText size="16" value="#{animals.costRegular}" maxlength="64" /&gt;
                          &lt;/p:column&gt;
                      &lt;/p:row&gt;
                      &lt;p:row&gt;
                          &lt;p:column styleClass="block"&gt; Extra Costs:   &lt;/p:column&gt;
                          &lt;p:column&gt;
                              &lt;p:inputText size="16" value="${aifBean.costNonRegular}" maxlength="64" /&gt;
                          &lt;/p:column&gt;
                          &lt;p:column styleClass="block"&gt; Extra Cost Description &lt;/p:column&gt;
                          &lt;p:column&gt;
                              &lt;p:inputTextarea rows="4" cols="40" value="#{animals.nonRegularDesc}" /&gt;
                          &lt;/p:column&gt;
                      &lt;/p:row&gt;
                      &lt;p:row&gt;
                          &lt;p:column styleClass="block"&gt; Comments &lt;/p:column&gt;
                             &lt;p:column colspan="3"&gt;
                                  &lt;p:inputTextarea rows="2" cols="80" value="#{animals.comments}" /&gt;
                          &lt;/p:column&gt;
                      &lt;/p:row&gt;
                      &lt;/p:panelGrid&gt;
                  &lt;/h:form&gt;
              &lt;/p:tab&gt;
              &lt;p:tab title="Medical History"&gt;
                  &lt;p:dataTable styleClass="w100pct" var="current" value="#{medical.getMedHistoryByAifNo(param.AIF_NO)}"&gt;
                      &lt;p:column headerText="Delete"&gt;
                          Delete
                      &lt;/p:column&gt;
  
                      &lt;p:column headerText="Procedure Name"&gt;
                          #{current.shortName}
                      &lt;/p:column&gt;
  
                      &lt;p:column headerText="Date"&gt;
                          #{current.treatmentDate}
                      &lt;/p:column&gt;
  
                      &lt;p:column headerText="Vet Information"&gt;
                          #{current.vetName} #{current.vetClinic}
                      &lt;/p:column&gt;
  
                      &lt;p:column headerText="Comments"&gt;
                          #{current.comments}
                      &lt;/p:column&gt;
                  &lt;/p:dataTable&gt;
              &lt;/p:tab&gt;   
              &lt;p:tab title="Documents"&gt;
                  &lt;h:form id="docListForm"&gt;
                      &lt;p:dataTable id="docListTable" styleClass="w100pct" var="current" value="#{documents.currentDocList}"
                                   paginator="true" rows="10" selection="#{documents.selectedDocs}"&gt;
  
                          &lt;p:column selectionMode="multiple" style="width:2%" /&gt;  
  
                          &lt;p:column headerText="Date"&gt;
                              &lt;h:outputText value="#{current.treatmentDate}" /&gt;
                          &lt;/p:column&gt;
  
                          &lt;p:column headerText="Document Type"&gt;
                              &lt;h:outputText value="#{current.group}" converter="com.rescuedb.DocGroupName" /&gt;
                          &lt;/p:column&gt;
  
                          &lt;p:column headerText="Description"&gt;
                              #{current.description}
                          &lt;/p:column&gt;
  
                          &lt;f:facet name="footer"&gt;  
                              &lt;p:commandButton id="docListDelete" value="Delete Selected Records" 
                                               icon="ui-icon-search" 
                                               update=":#{p:component('docListTable')}" 
                                               actionListener="#{documents.deleteReference}" &gt;
                                  &lt;f:param name="docNo" value="#{current.docNo}" /&gt;
                                  &lt;f:param name="refNo" value="#{animals.aifNo}" /&gt;
                                  &lt;f:param name="group" value="#{current.group}" /&gt;
                              &lt;/p:commandButton&gt;  
                          &lt;/f:facet&gt;
                      &lt;/p:dataTable&gt;
                  &lt;/h:form&gt;
              &lt;/p:tab&gt;
          &lt;/p:accordionPanel&gt;
  
      &lt;/div&gt;
  &lt;/ui:define&gt;
  &lt;/ui:composition&gt;
  </code></pre>
  
  <p>The managed bean that backs this page is as follows (this is fairly preliminary code, as I am still experimenting with PrimeFaces and JSF):</p>
  
  <pre><code>package com.rescuedb.beans.managed;
  
  import java.io.Serializable;
  import java.util.List;
  import java.util.Map;
  
  import javax.annotation.PostConstruct;
  import javax.faces.bean.ManagedBean;
  import javax.faces.bean.ViewScoped;
  import javax.faces.context.FacesContext;
  import javax.faces.event.ActionEvent;
  
  import org.apache.log4j.Logger;
  
  import com.rescuedb.Beans.DocMasterBean;
  import com.rescuedb.Beans.DAO.DocMaster;
  import com.rescuedb.Beans.DAO.DocXref;
  import com.rescuedb.Beans.Models.DocMasterDataModel;
  import com.rescuedb.Core.RescueException;
  
  @ManagedBean(name="documents")
  @ViewScoped
  public class DocumentManagedBean implements Serializable
  {
  
      static final long serialVersionUID = 5L;
  
      static Logger logger = Logger.getLogger(DocumentManagedBean.class);
  
      private transient DocMaster             docInfo;            // Document Master accessor object
      private transient DocXref               xrfInfo;            // Document Master accessor object
  
      private String  currentAifNo;
      private String  refNo;
      private String  docNo;
  
      /**
       * Contains a list of document records, wrapped in a DataModel, for the currently 
       * active foster animal.
       */
      private DocMasterDataModel currentDocList = null;           
  
      private DocMasterBean[] selectedDocs;
  
      public DocumentManagedBean()
      {
          logger.trace ("DocumentManagedBean.constructor");
          try {
              //
              // Retrieve the URL parameter from the context.
              //
              FacesContext       context    = FacesContext.getCurrentInstance();
              Map&lt;String,String&gt; paramMap   = context.getExternalContext().getRequestParameterMap();
              String             paramAifNo = paramMap.get("AIF_NO");
  
              if (paramAifNo != null) {
                  if (!paramAifNo.isEmpty()) {
                      currentAifNo = paramAifNo;
                      loadCurrentDocList();
                  }
              }
          } catch (Exception e) {
              logger.error ("Exception caught in DocumentManagedBean() constructor :: " + e.getMessage(), e);
          }
      }
  
      /**
       * Initialize the bean from the database.   
       */
      @PostConstruct
      public void initialize ()
      {
          logger.trace ("DocumentManagedBean.initialize");
          try {
              docInfo = new DocMaster();
              xrfInfo = new DocXref();
          } catch (Exception e) {
              logger.error ("Exception in DocumentsManagedBean.initialize() : " + e.getMessage(), e);
          }
      }
  
      public List&lt;DocMasterBean&gt; getDocList()
      {
          logger.trace ("DocumentManagedBean.getDocList");
          return docInfo.getRecordList();
      }
  
      /**
       * Retrieve the list of documents that are associated wit a specific foster animal.
       * &lt;p&gt;
       * @param aifNo
       * @return
       */
      public DocMasterDataModel getCurrentDocList()
      {
          logger.trace ("DocumentManagedBean.getCurrentDocList");
          return currentDocList;
      }
  
      /**
       * Load the document list for the currently active foster animal.
       */
      private void loadCurrentDocList()
      {
          DocMaster docMaster = null;
  
          logger.info ("DocumentManagedBean.loadCurrentDocList");
          try {
              docMaster = new DocMaster();
              if (currentAifNo != null) {
                  if (!currentAifNo.isEmpty()) {
                      docMaster.queryByRefNo (Integer.parseInt(currentAifNo));
                      currentDocList = new DocMasterDataModel (docMaster.getRecordList());
                      logger.info ("DocumentManagedBean.loadCurrentDocList :: currentDocList reloaded, length = " + docMaster.getRecordCount());
                  } else {
                      logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is empty, no records loaded.");
                  }
              } else {
                  logger.info ("DocumentManagedBean.loadCurrentDocList :: currentAifNo is null, no records loaded.");
              }
          } catch (Exception e) {
              logger.error ("Exception in DocumentsManagedBean.loadCurrentDocList() : " + e.getMessage(), e);
          }
      }
  
      public void deleteReference(ActionEvent event)
      {
          boolean        status;                // Status of the update.
          int            refNo = 0;
          int            docNo = 0;
  
          logger.info ("DocumentManagedBean.deleteReference");
          try {
              //
              // Retrieve the parameter of the request.
              //
              FacesContext       context    = FacesContext.getCurrentInstance();
              Map&lt;String,String&gt; paramMap   = context.getExternalContext().getRequestParameterMap();
              String             paramDocNo = paramMap.get("docNo");
              String             paramRefNo = paramMap.get("refNo");
              logger.info (String.format("DocumentManagedBean.deleteReference :: paramDocNo = [%s]", paramDocNo));
              logger.info (String.format("DocumentManagedBean.deleteReference :: paramRefNo = [%s]", paramRefNo));
  
              //
              // Retrieve the items necessary to delete the proper records.
              // The refNo parameter will only be specified when a specific cross-referenced
              // record is to be deleted.  If this value is missing, then the master document
              // is to be deleted.
              //
              if (paramRefNo != null) {
                  try {
                      refNo = Integer.parseInt (paramRefNo);
                      this.refNo = paramRefNo;
                  } catch (NumberFormatException e) {
                      refNo = 0;
                  }
              }
  
              //
              // The docNo has to be present.  If the refNo is zero, then we will delete the
              // master document.  If a refNo is present, then we will delete a cross reference.
              //
              if (paramDocNo != null) {
                  try {
                      docNo = Integer.parseInt (paramDocNo);
                      this.docNo = paramDocNo;
                  } catch (NumberFormatException e) {
                      docNo = 0;
                      String message = String.format ("Illegal value for docNo (%d)", docNo);
                      logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
                      throw new RescueException ("DS000091", message, "DocumentsManagedBean", "deleteReference");
                  }
              } else {
                  logger.error("DocumentManagedBean.deleteReference :: paramDocNo is null");
              }
  
              //
              // Delete the cross reference record.
              //
              if (refNo != 0) {
                  xrfInfo = new DocXref();
                  status  = xrfInfo.queryByCrossRef (docNo, refNo);
                  if (status != true) {
                      String message = String.format ("Error querying DOC_xref for refNo = %d, docNo = %d", refNo, docNo);
                      logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
                      throw new RescueException ("DS000092", message, "DocumentsManagedBean", "deleteReference");
                  } else {
                      status = xrfInfo.delete();
                      logger.warn("DocumentManagedBean.deleteReference :: Document XRef deleted");
                      // logger.warn("DocumentManagedBean.deleteReference :: TEST TEST TEST Document XRef not actually deleted");
                      if (status != true) {
                          String message = String.format ("Error deleting DOC_xref for refNo = %d, docNo = %d", refNo, docNo);
                          logger.error(String.format("DocumentManagedBean.deleteReference :: Exception Message [%s]", message));
                          throw new RescueException ("DS000093", message, "DocumentsManagedBean", "deleteReference");
                      } else {
                          loadCurrentDocList();
                          logger.error("DocumentManagedBean.deleteReference :: currentDocList reloaded");
                      }
                  }
              } else {
                  logger.error("DocumentManagedBean.deleteReference :: refNo is 0.  No Records were deleted.");
              }
          } catch (RescueException e) {
              logger.error ("RescueException in DocumentsManagedBean.deleteReference() :: " + e.getMessage(), e);
          } catch (Exception e) {
              logger.error ("Exception in DocumentsManagedBean.deleteReference()", e);
          }
      }
  
      public DocMaster getDocInfo() 
      {
          logger.info ("DocumentManagedBean.getDocInfo");
          return docInfo;
      }
  
      public void setDocInfo(DocMaster docInfo) 
      {
          logger.info ("DocumentManagedBean.setDocInfo");
          this.docInfo = docInfo;
      }
  
      public String getRefNo() 
      {
          logger.info ("DocumentManagedBean.getRefNo");
          return refNo;
      }
  
      public void setRefNo(String refNo) 
      {
          logger.info ("DocumentManagedBean.setRefNo");
          this.refNo = refNo;
      }
  
      public String getDocNo()
      {
          logger.info ("DocumentManagedBean.getDocNo");
          return docNo;
      }
  
      public void setDocNo(String docNo) 
      {
          logger.info ("DocumentManagedBean.setDocNo");
          this.docNo = docNo;
      }
  
      public DocMasterBean[] getSelectedDocs() 
      {  
          logger.info ("DocumentManagedBean.getSelectedDocs");
          return selectedDocs;  
      }  
  
      public void setSelectedDocs(DocMasterBean[] selectedDocs) 
      {  
          logger.info ("DocumentManagedBean.setSelectedDocs");
          this.selectedDocs = selectedDocs;  
      }  
  }
  </code></pre>
  
  <p>I have tried a number of different strategies, and have read a fair number of very detailed explanations of this process in other StackOverflow threads (Thank you, BalusC!), but have still been unable to actually invoke the action listener.</p>
  
  <p>My Environment is as follows:</p>
  
  <ul>
  <li>Java 1.6</li>
  <li>Eclipse Kepler (originally Juno)</li>
  <li>GlassFish 3.1.2</li>
  <li>PrimeFaces 3.5.0</li>
  </ul>
  
  <p>From a presentation perspective, the XHTML displays correctly.  The <code>&lt;p:dataTable&gt;</code> element is rendered just like the documentation and examples indicate, but when I attempt to delete a a row, the listener is never invoked.</p>
  
  <p>I have tried changing the update name several times.  Currently, the value of the <code>update</code> parameter is <code>profile:docListForm:docListTable</code>.</p>
  
  <p>Other posts seem to indicate that there was a problem with <code>&lt;p:commandButton&gt;</code> from within a <code>&lt;p:accordianPanel&gt;</code>, but that was for a previous version of PrimeFaces (3.2).</p>
  
  <p>I have tried moving the <code>&lt;p:commandButton&gt;</code> outside the <code>&lt;p:dataTable&gt;</code>  and also on each row, yet the behavior does not change.</p>