1 Reply Latest reply on Aug 10, 2012 4:14 AM by mali_karabulut

    refreshing @DataModel, nested Conversations

    roberto.roberto.dynamix.com.br

      Hi,
      I have this in Conversation:


      @AutoCreate
      @Name("alertsList")
      @Scope(ScopeType.CONVERSATION)
      public class AlertsList extends EntityQuery<Alert> {
      
          @DataModel(value = "alerts")
          @Override
          public List<Alert> getResultList() {
              return super.getResultList();
          }
      



      and a link in the view:



      <s:link action="#{myManager.read(alert)}">
        <h:outputText value="#{messages.ok}" /> 
      </s:link>
      



      the 'read' method starts a nested conversation:



      @Begin(nested = true, flushMode = FlushModeType.MANUAL)
      @End
      public void read(Alert alert) {
        alert.setStatus(Status.READ);
        this.getDAO().saveAndFlush(alert);
      }
      



      how can I update the 'alerts' DataModel from the parent conversation without using events (because I want to update only the 'alerts' instance in my parent Conversation, not in all existing Conversations) ?


      I tried 'alertsList.refresh()' in the read Method, but Seam Interceptors update the DataModel in the nested Conversation and the old DataModel remains in the parent.


      What you think about all this? is a correct way?

        • 1. Re: refreshing @DataModel, nested Conversations
          mali_karabulut

          I know this is an old thread but lately I spent a lot time on a similar issue and want to share what I came up with as as solution regarding this issue.

           

          Scenario:

          1- I have a list populated in a datatable on a xhtml page (/list.xhtml) with a long-running conversation(LRC).

          2- I have a link to create a new entity of this list that redirects to a new xhtml page(/create.xhtml), which also starts a nested conversation. (@Begin(nested=true))

          3- I fill in the form in this creation page and save the new entity.  (entityManager.persist(newEntity);)

          4- I click on the 'Return' button (which is a <h:commandButton> on the creation page with an action, not the confuse with browser back button) to return back to the original list page. Nested conversation is ended here. We now left with the parent LRC only. So far so good.

          5- The problem: Datamodel is not updated with the recently added entity, even if I call the 'list' method on the return event. The newly created entity is missing.

           

          I almost spent one day trying to figure out this problem and come up with this solution.

          Here the problem is the 'Return' button of the creation page runs in the nested conversation, thus even if list() method is called manually here in this step, it won't affect the original list in the parent conversation.

          The simple solution I found is to add a page action to the page.xml of the /list.xhtml page, which calls the list() method whenever the page is requested.

          <action execute="#{actionBean.list}"/> (this also eliminates the need for the @Factory method call for the datamodel since this page action is called whenever page is rendered)

           

          The 'Return' button of the /create.xhtml page navigates to the main page, destroying the conversation before redirect.

                    <navigation>

                                   <rule if-outcome="return">

                                           <end-conversation before-redirect="true"/>

                                           <redirect view-id="/list.xhtml"></redirect>

                                   </rule>

                    </navigation>

           

          We then get back to parent conversation,and in the mean time main page renders which in turn calls the list() method of the SFSB in the parent conversation, thus refreshing the list appropriately.

           

          There may be alternative work arounds on this  problem such as calling the Conversation.instance().pop() which "Pops the conversation stack, switching to the parent conversation", and then calling the list() method in the action method of the 'Return' button in order to refresh the list. Although this method does the job so that it refreshes the list on the parent conversation correctly, I here got stuck with killing the nested conversation here, since a call to '<end conversation>' destroys all the conversations from the top since we are in the parent conversation now. If we omit the end conversation part, this time nested conversations stay in the memory until destroyed by seam according to the conversation time-out. I would be very happy to hear your solutions on this matter.