7 Replies Latest reply on Sep 11, 2010 7:16 PM by lvdberg

    continue a long conversation?

    kinghoward

      My application seems unable to continue a conversation. I have a datatable, and commandLinks inside it. Whenever I click one of the links, a method is triggered on the SFSB, but a new conversation is initiated rather than continuing with the long conversation. I tried to use


      @Begin(join=true)



      on the @Factory method findMessages(), but when another method (select()) is triggered, we have a new conversation.


      Can someone please tell me why I have a new conversation? I want the conversation to continue so that I can inject value into @DataModelSelection field messageSelected.


      the bean:


      @Stateful
      @Scope(CONVERSATION)
      @Name("messageManager")
      public class MessageManagerBean implements Serializable, MessageManager
      {
      
           @DataModel(value="messageList", scope=PAGE)
           private List<Message> messageList;
      
           @DataModelSelection(value =     "messageList")
           @Out(required=false)
           private Message messageSelected;
      
           @Begin(join=true) 
           @Factory("messageList")
           public List<Message> findMessages()
           {
                this.messageList = new ArrayList<Message>();
                Message first = new Message("First", "This is a great message", true);
                this.messageList.add(first);
                Message second = new Message("Second", "This is an average message", false);
                this.messageList.add(second);
                Message third = new Message("Third", "This is a bad message", false);
                this.messageList.add(third);
                System.out.println("messageList now has size: " + messageList.size());
                return this.messageList;
           }
      
           public void select()
           {
                if (messageSelected!=null){
                     messageSelected.setRead(true);
                     System.out.println("in select(), for message: " + messageSelected.getTitle());
                }
                else{
                     System.out.println("in select(), NULL message");
                }
      
           }
      
           @End
           public void endConversation(){
                
           }
              
              ....
      
           @Remove @Destroy
           public void destroy() {}
      
      }



      view xhtml ignoring anything outside the datatable:


      <h:dataTable value="#{messageList}"  var="msg">
           <h:column>
                <f:facet name="header">
                     <h:outputText value="Read" />
                </f:facet>
                <h:selectBooleanCheckbox id="read" value="#{msg.read}"
                     disabled="true" />
           </h:column>
           <h:column>
                <f:facet name="header">
                     <h:outputText value="Title" />
                </f:facet>
                <h:commandLink id="link" value="#{msg.title}"
                     action="#{messageManager.select}" />
           </h:column>
      </h:dataTable>






        • 1. Re: continue a long conversation?
          lvdberg

          Hi Howard,


          try to stick to the same thread, because you still have the same problem. Not because we won't answer you, but its better for others who want to look up solutions.


          I don't think the Begin annotation should be placed on the Factory method. Switch to the form I mentioned in the other thread. So enter the page with an active conversation. These lines must be added to the pages.xml file which is under the WEB-INF directory.



          <page view-id="yourPage.xhtml"  >
               <begin-conversation join="true" />
          </page>
          



          • 2. Re: continue a long conversation?
            kinghoward

            thanks Leo!


            I just did that, and it did make conversation last, but now, the @DataModelSelection field messageSelected is still not getting anything injected into it, always null....


            any other suggestions!? thanks!


            H.


            i just add in my message class for reference here, the rest of the classes are pretty much the same as above with the @Begin moved to pages.xml as suggested:




            @Entity
            @Name("message")
            @Scope(EVENT)
            public class Message implements Serializable
            {
                    
                    public Message(){
                            this.title = "";
                            this.text = "";
                            this.read = false;
                    }
                    
                    public Message(String title, String text, boolean read){
                            this.title = title;
                            this.text = text;
                            this.read = read;
                    }
                    
               private String title;
               private String text;
               private boolean read;
            
               public String getTitle() {
                  return title;
               }
               public void setTitle(String title) {
                  this.title = title;
               }
               
               public String getText() {
                  return text;
               }
               public void setText(String text) {
                  this.text = text;
               }
               
               public boolean isRead() {
                  return read;
               }
               public void setRead(boolean read) {
                  this.read = read;
               }   
            }
            



            • 3. Re: continue a long conversation?
              lvdberg

              Hi Howard,


              Try




              @DataModelSelection
              @Out(required=false)
              private Message messageSelected;





              You are using the same context-var names for DataModel and DataModelSelection.


              Leo

              • 4. Re: continue a long conversation?
                kinghoward

                thanks again Leo.


                changed that, still getting null for DataModelSelection.


                I also tried to change the scope of my SFSB to SESSION, that didn't help.


                I was playing with a bunch of minor changes on the xhtml file inside the datatable, non of it helped.  e.g. i removed the selectBooleanCheckbox column. Also for h:commandLink, I moved the action field to be before the value field.


                Tried to change the scope of the Message class, and removing @Entity etc, also didn't help.


                For what I see with other people's posts on the same problem, changing the scope would help, but I tried all the different scopes, and non helped.


                I use h:commandLink instead of s:link which other people had problems with, so that should be fine.


                Other ideas? This really should work now... but it does not.


                H.

                • 5. Re: continue a long conversation?
                  lvdberg

                  Hi,


                  To be honest I never use @DataModelSelection (or @DataModelIndex for that matter), but direct method-calls with vars. Change the following:





                  <h:commandLink id="link" value="#{msg.title}"
                                 action="#{messageManager.select(msg)}" /> and change the bean
                  
                  
                  
                  public void select(Message m)      {
                  messageSelected = m; // Store it for further use; renind this is a DETACHED entity
                            if (messageSelected!=null){
                                 messageSelected.setRead(true);
                                 System.out.println("in select(), for message: " + messageSelected.getTitle());
                            }
                            else{
                                 System.out.println("in select(), NULL message");
                            }
                  
                       }
                  



                  This should really work now, so you must get the right answer. If there still something wrong with the conversation


                  Add also @In Conversation conversation; This can be used in you code to check the status of the conversation. It has different methods to check check the conversationId, if it is long-running or not.


                  Leo





                  • 6. Re: continue a long conversation?
                    kinghoward

                    woh! Finally! that did work! thanks Leo!


                    Now that I'm trying this, it seems the msg parameter will only be passed if the select() method returns a new page. If it does not return a new page (i.e. return type void instead of String), then the msg parameter will be null.


                    Why is that?


                    About @DataModelSelection: I can use it with the message example using DataModelSelection straight out of the seam distribution, and compile and deploy it using ant. but when I try to copy the code over to my own seam web project under eclipse, as we saw, it just didn't work.

                    • 7. Re: continue a long conversation?
                      lvdberg

                      Hi,


                      It depends on the way you use the output. If your pages are resulting from navigation rules in pages.xml, you need a String answer. You can also return a page directly (something like return myPage.xhtml.


                      You can also use dynamic rerendering with ajax, meaning you use the reRender attribute of a a4j:commandButton (or Link) and update parts of the page you're in at the moment.


                      Most of my applications are fully dynamic and only the metadata configuration pages are based on simple navigantion rules.


                      Just experiment with the possibilities of Seam together with JSF and you'll be surprised.


                      Leo