0 Replies Latest reply on Jul 23, 2009 1:53 AM by Arbi Sookazian

    Using Factory pattern with browser back button bug

    Arbi Sookazian Master

      We found a back button-related bug today in my Seam app that had to do with using @Factory with @DataModel to generate ListDataModel objects for my <rich:dataTable> components.

      User would navigate to page A, click edit link in dataTable for a row, (now the @Factory methods fire for the dataTables in the next JSF page), click browser back button, click edit for a different row.

      The use case is modeled using a LRC so all components (e.g. SFSB backing beans) are CONVERSATION-scoped.  So the bug was that we were seeing cached/stale data in the dataTables for the next page the 2nd time user clicks edit.

      I solved this problem but am not sure it is the best way to solve it.  I added an init() method to the 2nd page's backing bean.  And added a call to that method in my pages.xml:

      <page view-id="/RepairCaseDetails.xhtml">
               <description>Repair Case Details</description>
               <action execute="#{repairCaseDetails.init}"/> 
                    <rule if-outcome="cancel">
                         <end-conversation before-redirect="true"/>
                         <redirect view-id="/ManageEquipment.xhtml"/>

      NOTE: RepairCaseDetails.xhtml is the 2nd JSF page.

      The complication was that I have rich:modalPanel components in the 2nd page and those were making the init() to be executed two times each during load/display phase (possibly due to reRendering as well?)

      So then I added this in the 1st page's backing bean:

           private Boolean doInitRepairCaseDetails;
      public void processRepairHistorySelection()
                repairId = (Integer)repairHistorySelection[0];
                serialNumber = (String)repairHistorySelection[1];
                doInitRepairCaseDetails = true;
                log.info("in processRepairHistorySelection(): repairId = " + repairId + "; serialNumber = " + serialNumber);

      processRepairHistorySelection() is the method that is executed when user clicks the edit link in 1st page's dataTable edit column.

      Here is the init() method for 2nd page's backing bean:

      //asookazi: set the @DataModel List instances to null so the @Factory methods will fire.
           //this addresses the following bug:      from ManageEquipment page, click edit link in repair history, then click browser back button,
           //then click edit for different row in repair history dataTable, you'll see cached data from previous repairId's dataTables in RepairCaseDetails page.
           public void init()
                if (doInitRepairCaseDetails)
                     repairGeneralInfoList = null;               
                     equipmentRepairFindingCodeList = null;               
                     equipmentRepairProblemCodeList = null;          
                     equipmentRepairCostList = null;
                     totalCost = 0.00;
                     cost = 0.00;
                     doInitRepairCaseDetails = false;

      So now the @Factory methods are only executed after user clicks the edit link, and not when the modalPanels display.

      I have a feeling that this is not a good idea, but it does work:

           private Boolean doInitRepairCaseDetails;

      Any comments/suggestions?