11 Replies Latest reply on Feb 18, 2008 3:04 AM by eirirlar

    Named conversation and new instance redirected to Home? Best

    Tomas Cerny Novice

      Hi lets say that I have an elements table. I can pick one element and go to entityHome so my conversation name is entity.id and everything is ok.

      But I also have a navigation from my table to create new instance so I go to entityHomeEdit and my conversation is named new. After I save the new instance I want to redirect to entityHome , new entity has already id so it redirects as conversation namedentity.id ;(. That is wrong. Lets show you a code:

       <conversation name="personHome"
       parameter-name="personName"
       parameter-value="person-#{empty person.id ? 'new' : person.username}"/>
      
       <page view-id="/private/search/people/personHomeView.xhtml"
       conversation="personHome"
       conversation-required="true"
       no-conversation-view-id="/private/home.xhtml"/>
       <page view-id="/private/search/people/personHomeEdit.xhtml"
       conversation="personHome"
       conversation-required="true"
       no-conversation-view-id="/private/home.xhtml"/>
       <page view-id="/private/search/people/personHomeAjax.xhtml"
       conversation="personHome"
       conversation-required="true"
       no-conversation-view-id="/private/home.xhtml"/>
      


      So I can stick in my ManagerBean some condition but it is ugly. Do you have some better solution? Eg something like kill conversation when new entity is saved and create new conversation with different name.
      But it is in one request, can I do that? Is there access to the conversation from my ManagerBean, so I could kill the old named one (new) and build new named one (id).

      I am sure that we all goes through it. What is the best solution?

      Tomas

        • 1. Re: Named conversation and new instance redirected to Home?
          Pete Muir Master

          Ok. Explain this one again (it sounds interesting, but I'm tired, and I got lost ;)

          • 2. Re: Named conversation and new instance redirected to Home?
            Tomas Cerny Novice

            So imagine a scenario that you have one entity lets say people. You will provide a table of all people. You can edit people and add new people.

            Now you want to use jPDL and natural conversations (mix jPDL and pages.xml because jPDL does not offer you to specify conversation name).
            (note: I used to use deprecated method annotation for begin(id="foo.id"))


            You start a conversation whenever you click on a person from table or a new person button. You also want to join conversations with the same id.

            Scenerio 1: (problem join)

            you will click on person and will start conversation. In pages.xml is defined

            <conversation name="personHome"
             parameter-name="personName"
             parameter-value="person-#{empty person.id ? 'new' : person.username}"/>
            
             <page view-id="/private/search/people/personHomeView.xhtml"
             conversation="personHome"
             conversation-required="true"
             no-conversation-view-id="/private/home.xhtml"/>
            


            so your natural conversation has id==person.id

            Problem 1. raises when you want to join conversations with the same name (same person). Because the behavior is: start conversation, redirect to the page personHomeView.xhtml and name the conversation id==person.id as defined in pages.xml. The thing is that
            <conversation name="personHome"
             parameter-name="id"
             parameter-value="#{empty person.id ? 'new' : person.id}"/>


            should have parameter join. You cannot use annotation (join) on your selection method in session bean. Because at that time the new conversation has id=random and named id is made later from pages.xml.

            The main point is that I can use join at the time when I do not know which object is selected! so conversation has id=random which is renamed later in pages.xml, but if such a conversation id already exists it throws an error instead of joining.

            Note: this does not help because you do not know person instance at the time (otherwise as SeamBay)
            <h:commandButton ..action="select(person)" >
             <s:conversationName value=".."/>
             ..
            



            (SeamBay does not show this, it has passing id via get, but it seems like very un-maintainable and hacked solution)

            Scenerio 2: (problem conversation rename)
            Problem 2: you want to create a new person and then redirect to person home (jPDL).

            <page view-id="/private/search/people/personHomeEdit.xhtml"
             conversation="personHome"
             conversation-required="true"
             no-conversation-view-id="/private/home.xhtml"/>


            So you click on the button and call method that creates new object Person and starts new conversation. Then after method is done it redirects you from table to personHomeEdit and conversation is named id=new(note conversation id definition). Ok you fill out the form and saves the person. Then you are redirected to a page personHome. BUT now the Person instance has id now!!! so definition of conversationName evaluates it as conversation id=person.id and not id=new.
            personHome now expects conversation name id=person.id but such a conversation does not exist! so I am redirect to a default page.

            (Now I can manually check it in my method and in case of join redirect, but it is hack too and seam should have something better)

            What about make an clear example in your documnetation pages doing exactly this: one entity and two pages (Home and HomeEdit). You will use natural conversations (No hack as in SeamBay or maybe I did not look at it carefully). You can edit table entry(redirect to Home and then to HomeEdit and then HomeEdit) and create new (redirect to HomeEdit then to Home)

            Thanks for answer
            Tomas ;D

            • 3. Re: Named conversation and new instance redirected to Home?
              Pete Muir Master

              1) I think I see the problem. Can you not use <s:conversationPropagation type="join" /> in your page? I agree, it would be nicer to specify this in pages.xml, but unfortunately this isn't possible (this was the original design, but pages.xml isn't processed until much later in the lifecycle).

              2) Don't you want to end the conversation after saving the person?

              Thanks for the feedback :)

              • 4. Re: Named conversation and new instance redirected to Home?
                Tomas Cerny Novice

                I also thank you for the feedback so I tried this:

                 <h:commandLink
                 styleClass="left clearBoth"
                 action="#{teamManager.select(teamItem)}" value="select">
                 <s:conversationName value="teamHome"/>
                 <s:conversationPropagation type="join" />
                 </h:commandLink>
                


                And it does not work, because then the navigation does not work.
                I click the entry in table I want to edit and it does not redirect at all, method is called, but view stays in table. I think that to use <s:conversationPropagation type="join" /> I have to be inside a long-runnig conversation but I am not when I am in table page.

                Solution Problem 1. manually join conversations (exactly as you said problem is with different stage of life-cycle) - But I would buy a better solution ;D

                Solution Problem 2.
                a)Either End conversation and create new one
                b)Rename conversation in session bean
                c)Assign unique id to a session bean for all its life (in this case 'new')



                • 5. Re: Named conversation and new instance redirected to Home?
                  Pete Muir Master

                  No join should either join the existing conversation, or start a new one. If this doesn't work, its a bug - please report it in JIRA.

                  I see the problem with "problem 2" and I'll think about how to best help with it.

                  • 6. Re: Named conversation and new instance redirected to Home?
                    eirirlar Newbie

                    I'm struggling with similar issues regarding natural conversations, can't get them to join existing ones in a decent way.

                    +1 for better example in the docs.

                    Regards, Eirik

                    • 7. Re: Named conversation and new instance redirected to Home?
                      eirirlar Newbie

                      In my application I keep getting "Conversation id is already in use" when I try to use the same link twice to start the natural conversation. I thought I should have a look at the seam-bay example to figure out what I did wrong, but it turns out the same problem exists there. Please try for yourself (seam-2.1.0.A1):

                      1) log in
                      2) search for art, click on the painting
                      3) place a bid
                      4) visit www.whatever.com
                      5) go back to localhost and navigate to the same painting
                      6) place a bid -> Conversation id is already in use

                      Seams like there's a either a bug in the way seam-bay uses natural conversations, or a bug in the implementation of natural conversation. Either way, any help appreciated :)

                      Regards, Eirik

                      • 8. Re: Named conversation and new instance redirected to Home?
                        Tomas Cerny Novice

                        Hi Erik this is my working solution (I am handling conversation on my own)

                        entityManager that inherits generalManager

                        
                        @Begin(flushMode = FlushModeType.MANUAL, join = true, pageflow = "teamHomeFlow")
                         public String select(Team team) {
                         // set conversation
                         setConversationId(team.getId());
                         // manually join conversation
                         if(joinConversation()) {
                         return null;
                         } else {
                         return super.select(team);
                         }
                         }
                        
                        


                        generalManager

                        
                        /**
                         * joins conversations
                         * expects conversationName set with the same name as in pages.xml
                         *
                         * @return true if joined, false if not
                         *
                         * @see http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4126294#4126294
                         */
                         protected boolean joinConversation() {
                         //ConversationEntries.getInstance().updateConversationId(Conversation.instance().getId(), getConversationId());
                        
                         ConversationEntry ce = ConversationEntries.getInstance().getConversationEntry(conversationName + ":" + conversationId);
                         if(ce != null) {
                         ce.redirect();
                         getFacesMessages().add("Conversation already exists");
                         return true;
                         } else {
                         return false;
                        
                         }
                        
                         }
                        
                        


                        pages.xml

                        
                         <conversation name="teamHome"
                         parameter-name="team"
                         parameter-value="#{teamActionManager.conversationId}"/>
                        
                        


                        the idea is that every xxManager has unique instance ID (entity.ID) and this id is assigned to its whole conversational life (it solves the problem with creating new entity too)

                        Conversation has the same name as instance ID

                        I am joining that on my own by instance ID.

                        The disadvantages is your naming convention for conversation and its usage also in xxManager not only in pages.xml (coupling)

                        I hope that it helps. Good thing is that I tested it from various scenarios and it works!

                        I also thank you for comments to convince Seam documentation to do this as their example.

                        Tomas

                        • 9. Re: Named conversation and new instance redirected to Home?
                          eirirlar Newbie

                          Hi Tomas,

                          I was thinking about manually handling it, but since I only needed one type of conversation and wanted that one named, I ended up with this:

                          components.xml:

                          <core:manager conversation-id-parameter="forsendelseId" />


                          view.xhtml:
                          <h:dataTable id="forsendelser" value="#{forsendelser}" var="fors">
                          <h:column>
                          <s:link action="#{forsendelseaction.someactionmethod}">
                          <f:param name="forsendelseId" value="#{fors.id}" />
                          #{fors.id}
                          </h:column>
                          </s:link>
                          </h:dataTable>


                          action method annotation:
                          @Begin(join = true, id = "#{facesContext.externalContext.requestParameterMap.forsendelseId}")


                          Comments?

                          • 10. Re: Named conversation and new instance redirected to Home?
                            Tomas Cerny Novice

                            Hi Erik,

                            I would have two note for your solution.

                            1.

                            I do not know if Seam 2.1.0A1 undeprecated id in @Begin.
                            As you have

                            @Begin(join = true, id = #{facesContext.externalContext.requestParameterMap.forsendelseId}")
                            


                            There were some issues why it got deprecated and note from Gavin King was to use pages.xml for it. So if it is undeprecated then it is ok.

                            2.

                            <core:manager conversation-id-parameter="forsendelseId" />
                            


                            this will work. But if you have let say two completely different entity Types in your conversational context and they have the same id. You would actually merge them.

                            What would help is this:

                            <h:dataTable id="forsendelser" value="#{forsendelser}" var="fors">
                             <h:column>
                             <s:link action="#{forsendelseaction.someactionmethod}">
                             <f:param name="forsendelseId" value="#{fors.className}#{fors.id}" />
                             #{fors.id}
                             </s:link>
                             </h:column>
                            </h:dataTable>
                            


                            here you would know which entityType is in conversation context.

                            Please let me know what do think about that.

                            Tomas

                            • 11. Re: Named conversation and new instance redirected to Home?
                              eirirlar Newbie

                               

                              "enda" wrote:

                              There were some issues why it got deprecated and note from Gavin King was to use pages.xml for it. So if it is undeprecated then it is ok.


                              Actually it's not undeprecated yet but I couldn't find a way to do the same thing in pages.xml.

                              "enda" wrote:

                              here you would know which entityType is in conversation context.


                              Thanks for pointing that one out. It's definitely an applicable solution whenever you need to seperate between entity types. In my application it's not an issue however. (Anyways I'm a fan of putting such business keys in the domain model).

                              Thanks for the replies. Hope the Seam-boys fix the issues with natural conversations soon :)