3 Replies Latest reply on Apr 10, 2009 1:04 PM by Tomasz Wilczynski

    Seam conversation propogation issue

    Arshad Mahmood Newbie
      Hi,

      I have a bean that represents a hierarchical relationship (i.e. it points to itself). Think of it as representing a category/sub-category type relationship.

      I have view say /views/viewCategory.xhtml, that views a specific bean in the hierarchy. This views shows the current bean at the top, and any child beans as a list at the bottom. There three buttons, to edit the current bean, create a new child or cancel. The purpose of the cancel button is to take us back up the hierarchy to view the parent (and so on).

      The view viewCategory.xhtml, uses two components as categoryHome and category (both held in conversation scope). The categoryHome is used to fetch the current instance, and category is an alias for categoryHome.instance (just like the open18 example in Dan Allen's book).

      I am having a real problem with the cancel button. Whenever, I cancel it still shows me the old bean. I know the cancel has happened becauce if I output categoryHome.instance.id then I get the correct id, but the data in category is still the old bean.

      This looks like an ideal candidate for <end-conversation before-redirect="true" />, I have tried that in vain. I know this is a conversation issue, because if I reload the page then it shows the correct data for "category" (and also if I change the scope of "category" to event).

      My pages.xml navigation is as follows
      <page view-id="/views/viewCategory.xhtml">
      <param name="categoryId" value="#{categoryHome.id}" />

      <navigation from-action="action">
         <rule if="#{category.parent != null}">
            <end-conversation before-redirect="true" />
            <redirect view-id="/views/viewCategory.xhtml">
              <param name="categoryId" value="#{category.parent.id}" />
            </redirect>
          </rule>
         <rule if="#{category.parent == null}">
            <end-conversation before-redirect="true" />
            <redirect view-id="/views/index.xhtml" />
          </rule>
      </navigation>  
      </page>

      It seems as though end brefore redirect is not being honoured if I redirect to the same view.

      Can anybody help explain what is going on?
        • 1. Re: Seam conversation propogation issue
          Tomasz Wilczynski Newbie

          Robert,
          I'm not sure why you're ending conversation when switching to parent. Can't you pass the new id and reload categoryHome in a page action, inside the same conversation? Unless, you have your reasons not to do that. How do you start the conversation anyway?

          • 2. Re: Seam conversation propogation issue
            Arshad Mahmood Newbie
            Hi Tomasz,

            The problem is not with the categoryHome, I could just reload the instance as yiou say.

            The problem is with the category, this is fetched via a factory definition of the following form

            <factory name="category" value="#{categoryHome.instance}2 />

            Because this scoped to the conversation, I can't get an upadted category without ending the current conversation and starting a new one (because seam will find a not null value and hence not re-evaluate the expression).

            Maybe, I am doing this wrong. Perhaps, the category should be scoped to event. I was just following Dan Allens example, and really the end-conversation should work.

            As for when I start the conversation, well that is done on the index page which lists the root categories (i.e. those without parents) when a specific root caegory is viewed.


            • 3. Re: Seam conversation propogation issue
              Tomasz Wilczynski Newbie

              You could set category to null and outject it. Facotry method would be triggered every time you hit the page:


              <page view-id="/views/viewCategory.xhtml">
                <param name="categoryId" value="#{categoryHome.id}" />
                <action execute="#{categoryHome.find}" />
                ...
              </page>



              @In @Out Category category;
              
              @Override
              public Category find()
                super.find();
                category = null;
              }



              I'm nut sure which method it would best to override, but find() should do. It seems to me you need one long-running conversation, scoping category to event shouldn't be justified by factory not being recalled. Alternatively, you can give up the factory alias and use categotyHome.instance instead of category. In that case, all you need would be reloading instance on page action.