9 Replies Latest reply on Apr 19, 2007 6:35 AM by sammy8306

    End conversation and redirect problem

    sammy8306

      I'm having some trouble with conversation ending/propagation. Let me first sketch the essentials. We have 2 pages (blog.xhtml and newBlogEntry.xhtml), each backed by a seam component.
      blog.xhtml uses a dataTable to display the list of entries, each row containing a s:link to newBlogEntry.xhtml (which also doubles as editor for an existing entry when blogList optionally outjects a BlogEntry to the newBlogEntry component), and an h:commandButton calling a function in blogList to delete the entry. Notice that a long-runnning conversation is started at the creation of the blogList component, allowing for a get-request like
      /blog.seam?userId=1, as well as subsequent /blog.seam requests to work.

      @Name("blogList")
      @Scope(ScopeType.CONVERSATION)
      public class BlogEntryShowAction implements java.io.Serializable
      {
       ....
       @RequestParameter("userId")
       private Long userId;
      
       @DataModel
       List<BlogEntry> entries;
      
       public List<BlogEntry> getEntries() ...
      
       @Create @Begin
       public List<BlogEntry> getInitialEntries(){
       if(userId == null ){
       System.err.println("No UserId defined, couldn't start conversation");
       System.err.println("user==" + user);
       return null;
       }else{
       user = em.find(User.class, userId);
       return getEntries();
       }
       }
      }
      


      now the conversation started in blog.xhtml is ended in newBlogEntry.xhtml, which is backed by the following component, by calling addEntry():

      @Name("newBlogEntry")
      @Scope(ScopeType.CONVERSATION)
      public class BlogEntryNewAction implements java.io.Serializable
      {
       // a User and BlogEntry object are injected from blogList
       @In(create=true) // here we ensure an empty BlogEntry is created whenever none is passed
       ...
      
       @End
       public String addEntry(){
       user = getUser();
       if(user != null ) {
       try{
       // some persistance calls that work perfectly
       } catch (Exception e){
      
       //handle exc. stuff
       }
       }
      
       return "/blog.xhtml?userId=" + user.getId();
      
       }
      }
      


      Code that calls addEntry:
      ..
      <h:commandButton value="Add Entry" action="#{newBlogEntry.addEntry}">
       <f:param name="conversationPropagation" value="none"/>
      </h:commandButton>
      ..
      


      This page then redirects to our initial listing page, providing the userId again. My idea was that the conversation ends (that happens), gets garbage collected (that works, checked using debug.seam after clicking the add entry button and the succesful redirect). However, something strange (at least for me it is), is that a new conversation is not started directly after the redirect. I can see the
      (up-to-date, modified) entries, but the conversation-context does not exist anymore (the link after redirect looks something like /blog.seam?userId=1&cid=2, but conversation 2 has already ended) ?! Only when I click the delete button on this listing page (resulting in a postback to the same page), the getInitialEntries is called again. However, this will obviously fail, since the userId is not propagated in this (JSF) post action.

      The questions:

      * Why is a new blogList component not created instantly after the redirect (the long-running conversation is obviously ended, so in my mind it would be impossible to render the blog.xhtml case without constructing a new blogList component)
      * I could solve this by trying to hack the userId get-parameter into the action of all the buttons on the page... I haven't succeeded in that yet, and it would be a hack, right?
      * Any other ideas how I might solve this?


      Thanks,

      Sander