4 Replies Latest reply on Jan 7, 2007 10:42 PM by pdpantages

    Refreshing dataTable - Too many conversation

    fabboco

      Hi guys,

      I actually need help from expert people.

      I have a jsp page that shows a data table

      <f:view>
       <f:loadBundle basename="messages" var="msgs" />
       <h:form>
       <br>
       <t:dataTable id="cd" var="cd" preserveDataModel="false" value="#{cdList}" width="100%" ......>
      
       <h:column>
       <f:facet name="header">
       <h:outputText value="titolo" />
       </f:facet>
       <h:outputText value="#{cd.titolo}" />
       </h:column>
       </t:dataTable>
       </h:form>
      </f:view>
      


      and a session bean

      @Stateful
      @Name("TestManager")
      @Scope(ScopeType.SESSION)
      @Transactional
      public class TestManagerBean implements Serializable, TestManager
      {
       @PersistenceContext(type = PersistenceContextType.EXTENDED)
       private EntityManager em;
      
       @DataModel(value = "cdList")
       private List<Cd> cdList;
      
       public TestManagerBean()
       {
       }
      
       @Create
       public void create()
       {
       }
      
      
       @Factory("cdList")
       @Begin(join = true)
       public void findAll()
       {
       System.out.println("findAll");
      
       Query q = em.createQuery("select o from Cd o");
      
       cdList = q.getResultList();
       }
      
      
       @Remove
       @Destroy
       public void destroy()
       {
       }
      
      }
      


      When the page is loaded the first time, the findAll function is called and the page shows the data correctly.

      When the page is refreshed the findAll is not called again and the page doesn't show changes appened to the database.

      So I decided to add the following function:

      public void onListLoad()
      {
      
       cdList = null;
      
      }
      


      and I changed the pages.xml:

      <page view-id="/Test.jsp" action="#{TestManager.onListLoad}" />
      


      Now refreshing the page the findAll function is recalled and all database changes are shown.

      The problem is that A NEW CONVERSATION is started at each refresh.

      I have tried many options that do not work:

      1) annotate the onListLoad function with @Begin(join=true)
      2) modify pages.xml
      <page view-id="/Test.jsp" action="#{TestManager.onListLoad}" >
       <begin-conversation join="true"/>
      </page
      

      3) add a remoting call to onListLoad directly from the page:
      function startup()
      {
       Seam.Remoting.getContext().setConversationId(conversationId);
       Seam.Component.getInstance("TestManager").onListLoad(startupCallback);
      }
      
      function startupCallback(operation)
      {
       alert(Seam.Remoting.getContext().getConversationId());
      }
      
      .....
      
      <body onload="startup()">
      
      ......
      
      


      Can anyone give me the right solution ?

      Thank you

      Ragards

      Fabrizio


        • 1. Re: Refreshing dataTable - Too many conversation

          Taking a step back, why are you trying to start a conversation with a session scoped component?

          • 2. Re: Refreshing dataTable - Too many conversation
            fabboco

            Norman,

            I have shown only a small part of my code.

            I have information that should be shared between different conversation so I decided to put the TestManagerBean into the session.

            Anyway, I have changed the scope from SESSION to CONVERSATION but the behaviour is the same.

            Each time I refresh the page that contains the dataTable a new conversation is started.

            Any idea ?

            Thank you

            Fabrizio

            • 3. Re: Refreshing dataTable - Too many conversation
              fabboco

              After some experiments I realized that:

              1) If I start the Test page from the browser with localhost:8080/application/Test.seam and I refresh the page a new conversation is started. This is true if and only if I have a call to the TestBeam (ex <h:outputText value="#{TestManager.property}"></h:outputText> or the dataTable)
              If I have not a call to the TestBean the conversation is not even started.

              Let me say that if I start the Test page directly from the browser the page itself is 'detached' from the conversation, or in other words, the page can starts a conversation but it is not able to be attached to it.

              2) If I start the Test page from a different page (StartTest, which does not start any conversation) and I start the TestPage calling the startPage method, I am able to refresh the page as much I like without new conversation starts. This is true even if I have <page view-id="/Test.jsp" action="#{TestManager.onListLoad}" /> in the pages.xml. Obviously the table is refreshed (it was my original problem !!).

              Let me say that in this case the Test page is 'attached' to its conversation. There is a clue of the 'attachement': the URL in the browser is: localhost:8080/application/Test.seam?conversationId=number

              3) Removing @Begin(join=true) from the findAll method no conversation at all is started (!!! ???)

              4) The behaviour is the same if I put the bean either into the SESSION or into the CONVERSATION

              Now, question is: How can I make the Test page knows that it is attached to a conversation (or better that I will be attached to a conversation) when I start it directly from the browser ?

              Comments and help are welcome.

              Fabrizio



              Test page

              <f:view>
               <f:loadBundle basename="messages" var="msgs" />
               <h:form>
               <br>
               <t:dataTable id="cd" var="cd" preserveDataModel="false" value="#{cdList}" width="100%" ....>
              
               <h:column>
               <f:facet name="header">
               <h:outputText value="titolo" />
               </f:facet>
               <h:outputText value="#{cd.titolo}" />
               </h:column>
               </t:dataTable>
              
               <br>
               <hr>
               <h:outputText value="#{TestManager.property}"></h:outputText>
               <hr>
               <br>
               <h:commandLink action="#{TestManager.onListLoad}" value="Reload">
               </h:commandLink>
              
               </h:form>
              </f:view>
              


              StartTest page
              <f:view>
               <f:loadBundle basename="messages" var="msgs" />
               <h:form>
               <h1>Start Page</h1>
               <hr>
               <br>
               <h:commandButton action="#{TestManager.startPage}" value="Start Page" />
               </h:form>
              </f:view>
              


              Bean

              @Stateful
              @Name("TestManager")
              @Scope(ScopeType.SESSION)
              @Transactional
              public class TestManagerBean implements Serializable, TestManager
              {
               @PersistenceContext(type = PersistenceContextType.EXTENDED)
               private EntityManager em;
               private String property= "DISPLAY";
              
               @DataModel(value = "cdList")
               private List<Cd> cdList;
               public TestManagerBean()
               {
               }
              
               @Create
               public void create()
               {
               }
              
               @Factory("cdList")
               @Begin(join=true)
               public void findAll()
               {
               Query q = em.createQuery("select o from Cd o");
               cdList = q.getResultList();
               }
              
               @Remove
               @Destroy
               public void destroy()
               {
               }
              
               public void setProperty(String operation)
               {
               this.property = operation;
               }
              
               public String getProperty()
               {
               return property;
               }
              
               public void onListLoad()
               {
               cdList = null;
               System.out.println("reload");
               }
              
               public String startPage()
               {
               return "/Test.jsp";
               }
              }
              


              • 4. Re: Refreshing dataTable - Too many conversation
                pdpantages

                Hello Fabrizio,
                I am a bit of a newbie with seam but I have learned to watch for the "conversationId=xxx" on the browser status and on links. Seam will not be able to "find" the long-running conversation if the the ID is missing, & so will create a new converasation. If you look at the link generated by the h:commandLink you will probably see that the ID is missing. If you add <s:conversationId> or use <s:link> instead, it should show up and you should get the behaviour you want.