1 Reply Latest reply on Mar 19, 2007 6:00 AM by avbentem

    How to correctly use @DataModel's rowAvailable?

      Hi all,

      The DVD Store example shows using @DataModel, @Factory and JSF's isRowAvailable():

      @DataModel
      List<Order> orders;
      
      @DataModelSelection
      @Out(value="myorder", required=false, scope=ScopeType.CONVERSATION)
      Order order;
      
      @Begin @Factory("orders")
      public String findOrders() {
       :
      }


      <f:subview rendered="#{!orders.rowAvailable}">
       <p>You have not placed any orders.</p>
      </f:subview>


      The above works fine as long as the URL is not reloaded (Ctrl-R in the browser).

      However, when the URL includes a conversation ID (like &cid=123) then upon reloading the page, rowAvailable might yield false (as rowIndex == -1) while rowCount > 0. Is this the expected behavior?

      For example:

      In the online demo (which might be out of date, but I get the same behavior in my own code) clicking "My orders" works fine. Then, clicking Show Details for some order will make the URL include a &cid parameter (in fact named conversationId in that example, like showorders.seam?conversationId=123). Next, Ctrl-R or "Go" for that URL results in "You have not placed any orders". At this point the debug page shows, for example:
      Component (orders)
       class class org.jboss.seam.jsf.ListDataModel
       dataModelListeners []
       rowAvailable false
       rowCount 22
       rowData java.lang.IllegalArgumentException[row is unavailable]
       rowIndex -1

      Next, clicking on "My orders" again (which has propagation="none") will correctly show the list again. This, however, triggers the @Factory method, and thus fetches fresh results from the database.

      In my own code I'm now using rowCount, just like in all the other examples that use @Datamodel. But I'm still wondering if this is the expected behavior? Does one need some additional setup (such as scope in the @DataModel) when relying on isRowAvailable()?

      Thanks,
      Arjan.

        • 1. Re: How to correctly use @DataModel's rowAvailable?

          In fact org.jboss.seam.jsf.ListDataModel delegates most of its functionality to javax.faces.model.ListDataModel (link broken when I write this; see also the API). The Seam code includes:

          private void readObject(ObjectInputStream ois) throws IOException,
           ClassNotFoundException
          {
           this.setWrappedData( ois.readObject() );
           this.setRowIndex( ois.readInt() );
          }

          I assume readObject() throws an exception when the ObjectInputStream is not null but somehow emtpy, so I assume the readInt() could not yield -1 above, as writeObject sets it using getRowIndex().

          Still: could using the wrong scope somehow mess this up...? Note that Order does implement serializable:
          @Entity
          @Table(name="ORDERS")
          public class Order implements Serializable

          Any thoughts welcome!
          Arjan.