2 Replies Latest reply on Nov 12, 2007 12:38 PM by asookazian

    SFSB session scope with Factory method conversation scope: h

    asookazian

      sorry, this is a long one...

      I have a use case which may require two SFSB's for a facelet. The facelet has a h:dataTable and a rich:modalPanel (which has a4j:form embedded in it). The main SFSB for the dataTable's form was conversation scoped. I am using the @Factory and @DataModel tag team annotations to outject the DataModel List for the dataTable in the facelet.

      The second SFSB which handles form submissions from a rich:modalPanel was session scoped b/c the popup form submissions are not immediately persisted to the DB tables. I was injecting the second SFSB into the main SFSB (which I'm not sure is a good idea or not with Seam apps).

      So I decided to refactor this implementation and move all the logic/methods/variables from the second SFSB into the main SFSB (idea being to have one SFSB per facelet).

      I've tried different combinations of configurations with the @Factory annotation and have found the following (as is basically explained on pg. 68 of the Seam reference pdf for 2.0.0.GA):

      Since now there is only one SFSB and it is session scoped (to keep track of the modalPanel submitted form data until the main form is submitted), I needed a conversation or request scoped Factory method. Otherwise, the factory method will only be called once per session. There are multiple submit buttons (one per row) on the main form. So when user submits a row for persistence, the Factory method needs to fire again before dataTable is re-rendered so that the data is current.

      So I tried the first style as below:

      @Factory(value="customerList",scope=ScopeType.CONVERSATION)
      public List<Customer> getCustomerList() {
      return ... ;
      }


      The problem with this solution is that I get

      java.lang.NumberFormatException: For input string: "rowCount"


      when I check for the List's rowCount in the facelet as below:

      <h:dataTable value="#{customerList}" rendered="#{customerList != null and customerList.rowCount > 0}">


      Also, method not found for
      #{customerList.getRowIndex()}


      I think the reason I'm having these problems is b/c the @DataModel is not being used and therefore no outjection of a DataModel object that the JSF can use to render the dataTable (i.e. a regular List does not have a rowCount property or getRowIndex() method). I'm not sure I can even use a DataModel with this first style.

      So I try the second style as follows:

      @DataModel List<Customer> customerList;
      
      @Factory("customerList")
      public void initCustomerList() {
      customerList = ... ;
      }


      The problem with this solution is that b/c the @Factory annotation can't have a conversation scope when the method returns void, the initCustomerList() method will only get executed once per session (and I need it to exec per request/conversation).

      So what am I doing wrong and/or how can I solve this use case with a single facelet, a single SFSB, and ...??? I think I tried PAGE scope with @DataModel and it didn't help or work. From the Bauer talk it sounds like PAGE context is useful with Ajaxified Seam apps.

      I looked at the @Unwrap and manager component pattern as well but that forces the annotated method to be called every time the context variable is referenced (I'm assuming in the facelet???) So not sure if that's appropriate or not.

      Sounds like if I can get rowCount of the List and getRowIndex() equivalent for the List, I might be ok EXCEPT for I lose out on the @DataModelSelection and @DataModelSelectionIndex for processing a clicked row in the dataTable (which in this case, the query is based on two tables/entities).

      Basically: how can I get this to work for my use case with @Factory and the @DataModel* anntotations with one facelet and one SFSB???

      Please help, I'm frustrated and confused... thx.

        • 1. Re: SFSB session scope with Factory method conversation scop
          pmuir

           

          "asookazian" wrote:
          I was injecting the second SFSB into the main SFSB (which I'm not sure is a good idea or not with Seam apps).


          Thats fine

          So I decided to refactor this implementation and move all the logic/methods/variables from the second SFSB into the main SFSB (idea being to have one SFSB per facelet).


          You can use as many SFSB per facelet as you like.

          I've tried different combinations of configurations with the @Factory annotation and have found the following (as is basically explained on pg. 68 of the Seam reference pdf for 2.0.0.GA):

          The problem with this solution is that I get

          java.lang.NumberFormatException: For input string: "rowCount"


          when I check for the List's rowCount in the facelet as below:

          <h:dataTable value="#{customerList}" rendered="#{customerList != null and customerList.rowCount > 0}">


          Also, method not found for
          #{customerList.getRowIndex()}


          Try .size() for a list.

          Simplest solution is to use 2 correctly scoped Seam components.


          • 2. Re: SFSB session scope with Factory method conversation scop
            asookazian

            OK, thx a lot! I'll stick with my original design then (two SFSB's, one conversation scoped and one session scoped).