0 Replies Latest reply on Nov 17, 2009 1:50 PM by Tanya Ruttenberg

    Cannot persist or update from editable datatable

    Tanya Ruttenberg Expert

      I'm trying to set up an editable dataTable along the same lines as the example in richfaces demo. I am using a seam generated project so my backing beans are extensions of EntityHome (hope I'm saying this correctly).

      I have a datatable that contains 2 one-to-one entities, Devices and DevTags. I want to be able to edit the DevTag in a modalPanel component.

      <rich:dataTable id="dataTable"
       value="#{officeViewHome.instance.devices}" var="_devices"
       rowKeyVar="rowId" ajaxKeys="#{devTagsHome.rowsToUpdate}">
       <rich:column>
       <f:facet name="header">Row ID</f:facet>
       <h:outputText value="#{rowId}" id="rowid" />
       </rich:column>
       <rich:column>
       <f:facet name="header">
       <h:outputText value="Hostname" />
       </f:facet>
       <h:outputText value="#{_devices.devName}" id="hostname" />
       </rich:column>
       <rich:column>
       <f:facet name="header">
       <h:outputText value="Platform" />
       </f:facet>
       <h:outputText value="#{_devices.devPlatform}" id="platform" />
       </rich:column>
       <rich:column>
       <f:facet name="header">
       <h:outputText value="Soft Serial Number" />
       </f:facet>
       <h:outputText value="#{_devices.devSerialNum}"
       id="softSerialNum" />
       </rich:column>
       <rich:column>
       <f:facet name="header">
       <h:outputText value="DEvID" />
       </f:facet>
       <h:outputText value="#{_devices.devId}" id="devId" />
       </rich:column>
       <rich:column>
       <f:facet name="header">
       <h:outputText value="Asset Tag" />
       </f:facet>
       <h:outputText value="#{_devices.devTag.devTagId}" />
       </rich:column>
       <rich:column>
       <f:facet name="header">
       <h:outputText value="Hard Serial Tag" />
       </f:facet>
       <h:outputText value="#{_devices.devTag.devSerialNum}" />
       </rich:column>
      
       <rich:column>
       <f:facet name="header">Action</f:facet>
      
       <a4j:commandLink id="editLink"
       onclick="#{rich:component('editPanel')}.show()"
       reRender="assetTagPanel">
       <h:graphicImage value="/img/icons/edit.gif" style="border:0" />
       <f:setPropertyActionListener value="#{_devices.devId}" target="#{devTagsHome.devTagsDevId}" />
       <f:setPropertyActionListener value="#{rowId}" target="#{devTagsHome.currentRow}" />
       </a4j:commandLink>
       <rich:toolTip for="editLink" value="Edit Tag"
       rendered="#{not empty _devices.devTag.tagId}" />
       <rich:toolTip for="editLink" value="New Tag"
       rendered="#{empty _devices.devTag.tagId}" />
       </rich:column>
      
       </rich:dataTable>
      
       <rich:modalPanel id="editPanel" autosized="true" width="450">
       <f:facet name="header">Asset Tag</f:facet>
       <f:facet name="controls">
       <h:panelGroup>
       <h:graphicImage value="/img/modal/close.png"
       id="hideEditPanel" styleClass="hidelink"
       onclick="#{rich:component('editPanel')}.hide()" />
       </h:panelGroup>
       </f:facet>
       <h:form>
       <rich:messages for="assetTagPanel" style="color:red;"></rich:messages>
       <a4j:outputPanel ajaxRendered="true" id="assetTagPanel">
      
       <h:panelGrid columns="2">
       <h:outputText value="Serial Number. Change if necessary" />
       <h:outputText value="#{devTagsHome.instance.devSerialNum}"
       rendered="#{not empty devTagsHome.instance.devSerialNum}" />
       <h:outputText value="Asset Tag" />
       <h:inputText value="#{devTagsHome.instance.devTagId}" />
       <h:outputText value="Comment" />
       <h:outputText value="#{devTagsHome.instance.comment}" />
       <h:outputText value="Single Site Code" />
       <h:outputText value="#{officeViewHome.officeViewSiteCode}" />
       </h:panelGrid>
       </a4j:outputPanel>
       <a4j:commandButton value="Persist"
       actionListener="#{devTagsHome.persist}"
       oncomplete="#{rich:component('editPanel')}.hide()"
       reRender="dataTable" />
       <a4j:commandButton value="Update"
       actionListener="#{devTagsHome.update}"
       oncomplete="#{rich:component('editPanel')}.hide()"
       reRender="dataTable" />
       </h:form>
       </rich:modalPanel>
      


      The only field I need to edit is devTagId and then I want to save my change by clicking on Update. The result is a nullPointerException and when I run in the debugger and stop on the "update()" method, sure enough DevTagsHome is empty so of course it cannot be updated.


      The data populates the modalPanel just fine so I know the devTags.instance is being found correctly. Why, when I get to devTags.update() does my app act like it has never seen this devTag before?

      Here is DevTagsHome.java


      @Name("devTagsHome")
      public class DevTagsHome extends EntityHome<DevTags> {
      
       private Integer devTagsDevId;
       private Set<Integer> rowsToUpdate;
       private Integer currentRow;
      
       // Use devId to find the instance rather than tagId
       @Override
       public Object getId() {
      
       if (devTagsDevId == null) {
       return (Integer) super.getId();
       }
       return (Integer) getEntityManager().createQuery("select d.tagId from DevTags d " +
       "where d.devId=:devId ").setParameter("devId", devTagsDevId).
       getSingleResult();
      
       }
      
      
       protected DevTags createInstance() {
       DevTags devTags = new DevTags();
       return devTags;
       }
      
       public void load() {
       if (isIdDefined()) {
       wire();
       }
       }
      
       public void wire() {
       getInstance();
       }
      
       public boolean isWired() {
       return true;
       }
      
       public DevTags getDefinedInstance() {
       return isIdDefined() ? getInstance() : null;
       }
      
       @Override
       public String update() {
       // TODO Auto-generated method stub
       rowsToUpdate.clear();
       rowsToUpdate.add(currentRow);
       return super.update();
       }
      
       @Override
       public String persist() {
       // TODO Auto-generated method stub
       rowsToUpdate.clear();
       rowsToUpdate.add(currentRow);
       return super.persist();
       }
      
      
      }


      TDR