8 Replies Latest reply on Mar 5, 2009 1:28 AM by Tim Evers

    Conversational Scope Behavior: Inconsistent?

    Francisco Jose Peredo Noguez Master

      With JSP, we could only choose between page,request,session and application scope... EJBs gave us the option between stateless and stateful (session) scope, but until Seam we didn't have
      conversational scope.


      Now, with all the other scopes, things works in a particular way all the time, if I configure something as stateless, I know it is going to be stateless all the time, I know that each time I ask for that component I am going to get a different instance. Same thing goes for components in the page,request,session and application scope... but, if my component is it conversational scope, that its behavior is undefined.


      If I am in a TC, it will behave in one way, and if I am in a LRC it will behave in another way, not, this is can be seen as a feature (you can enhance an TC in to LRC) but it also means you can not use TC once you enter LRC mode. Conversational Scope is the only scope that has two mutually exclusive operation modes.


      So... what to do if I want to store in a TC and at the same time store something else in a LRC ?



      What about a new feature that allowed us to specify a non promotable TC component? something like:


      @Out(scope=ScopeType.TEMP_CONVERSATION)
      private Type object
      



      or  ( as in RoR? )


      @Out(scope=ScopeType.FLASH)
      private Type object
      



      Regards,


      Francisco


        • 2. Re: Conversational Scope Behavior: Inconsistent?
          Tim Evers Master

          This is actually one of the biggest problems I personally have with SEAM. It lacks the ability to control conversations easily. Passing data from one conversation to another is difficult when I specifically do not want the conversations to be joined. Like your example where you want a bean to remain as a temporary conversation but be able to pass data to a long running conversation.


          However, I think in your situation maybe you should be using either EVENT or PAGE scope. Essentially a temporary conversation is very similar to a PAGE scoped bean. (Not the same but probly close enough to make it work)


          Myself and a few others have written our own Navigation Controllers that allow us to control the passing of data from one conversation to another and know exactly when a new conversation is being created etc. After writing the NavigationManager conversation management became an absolute breeze, and everyone on the team was able to focus on writing business logic instead of worrying about when and where their seam conversations were starting/joining/ending.

          • 3. Re: Conversational Scope Behavior: Inconsistent?
            Francisco Jose Peredo Noguez Master

            Tim Evers wrote on Mar 03, 2009 02:41:


            This is actually one of the biggest problems I personally have with SEAM. It lacks the ability to control conversations easily. Passing data from one conversation to another is difficult when I specifically do not want the conversations to be joined. Like your example where you want a bean to remain as a temporary conversation but be able to pass data to a long running conversation.


            However, I think in your situation maybe you should be using either EVENT or PAGE scope. Essentially a temporary conversation is very similar to a PAGE scoped bean. (Not the same but probly close enough to make it work)



            PAGE wouldn't work, because what I want is precisely to pass a value from one page in to another. EVEN I believe it was the same as request and not as long as CONVERSATION in Temporary Mode... but maybe I am wrong...




            Myself and a few others have written our own Navigation Controllers that allow us to control the passing of data from one conversation to another and know exactly when a new conversation is being created etc. After writing the NavigationManager conversation management became an absolute breeze, and everyone on the team was able to focus on writing business logic instead of worrying about when and where their seam conversations were starting/joining/ending.



            Yes, navigation controllers could be the answer, lately I have been evaluating AribaWeb, its SeamGen equivalent seems a lot more mature, and its navigation is 100% code based and IMO its API is more elegant than the one of Wicket... I wonder how hard would it be to integrate it with Seam/WebBeans




            • 4. Re: Conversational Scope Behavior: Inconsistent?
              Francisco Jose Peredo Noguez Master

              Since AFAIK The event (request) context spans a server request, from restore view to render response, and redirects constitute a new server request EVENT will not work as a substitute for TC while a LRC is running.


              Am I wrong?

              • 6. Re: Conversational Scope Behavior: Inconsistent?
                Tim Evers Master

                I think this comes down to an understanding of CONVERSATION scoped beans. I see no need for a TEMP_CONVERSATION. Every time I have thought it was needed I realised I just needed to change how I was thinking about SEAM.



                You should only use CONVERSATION scoped beans IF they are required in the Conversation.
                For beans that you only want to live a short time you use the PAGE or EVENT scope and then in whatever action you call pass your data from your PAGE/EVENT scoped bean to your CONVERSATION scoped bean to store it.


                The only issue that exists around CONVERSATION scope is the inability to pass data from one conversation to another without joining that conversation or using some session bean.


                However, maybe I'm just not understanding your problem. Could you please give an example of what you are trying to do and maybe it will make more sense.

                • 7. Re: Conversational Scope Behavior: Inconsistent?
                  Francisco Jose Peredo Noguez Master

                  Tim Evers wrote on Mar 04, 2009 01:44:


                  I think this comes down to an understanding of CONVERSATION scoped beans. I see no need for a TEMP_CONVERSATION. Every time I have thought it was needed I realized I just needed to change how I was thinking about SEAM.



                  Maybe I need to think how I was thinking about Seam, but I prefer that Seam changed to make it easier to think about it ;)




                  You should only use CONVERSATION scoped beans IF they are required in the Conversation.



                  Temporary or Long? That is the big problem, if I should only use CONVERSATION for LRC then why they are not long by default? There are many cases where TC are more convenient.. I should I be forced to stop using TC to pass information to the next request (as RoR flash scope does) only because I am using a LRC ? I do not see an advantage in that limitation... do  you see it?



                  For beans that you only want to live a short time you use the PAGE or EVENT scope and then in whatever action you call pass your data from your PAGE/EVENT scoped bean to your CONVERSATION scoped bean to store it.



                  And for beans that I want have in this request, that you I want to use on the next request, but want to be forgotten after the next request is finished, what do I do?



                  The only issue that exists around CONVERSATION scope is the inability to pass data from one conversation to another without joining that conversation or using some session bean.




                  And the issue of trying to pass data to the next request, but also wanting that data to be forgotten after the next request is finished (like in a TC), while an LRC is running... how do you solve that?



                  However, maybe I'm just not understanding your problem. Could you please give an example of what you are trying to do and maybe it will make more sense.



                  Navigation... to promote reuse it should be possible to modularize it... lets say you already have a module that knows how to do CRUD to particular entity x mapped to a table X, you have your Edit and List .xhtml  and you .page.xhtml files, and your Home and your List java files.


                  Now, lets say you have another navigation module that represents a complex business process, and one of the steps in that complex business process is to modify the rows in x, so you say, I'll just call my X management module and let the user use it for doing any changes, and then resume my main proceess.


                  Now, since your X management module can be called as standalone  (accessing it from the main menu of the application) or as one of the steps of the complex business process its code should work with SESSION as the background or with an LR CONVERSATION as the background...


                  But it turns out it does not: Navigation rules are not reusable in Seam... (and they should be...) because the Scoping/Navigation architecture in Seam is inconsistent, a navigation flow can not be called inside a another navigation flow, and, isn't that what conversations were supposed to be about? about interrupting what you are currently doing, doing something else, and then continuing where you left?







                  • 8. Re: Conversational Scope Behavior: Inconsistent?
                    Tim Evers Master

                    You know, maybe we should set up an example and ask the jboss guys explain how they would approach the situation.


                    I have the exact scenario that you posed. We tried using SEAM's default navigation abilities and could never get it to work properly. There is no way to be in a long running conversation and pass data to another long running conversation and keep them seperate, or in your case keep your temporary conversation temporary and not have it become long running when passing data to your LRC. All of this navigation is probably able to be done using pages.xml, but I think in large applications most people aggree that pages.xml is not a viable solution and really xml is not the spot to have logic. It is too far removed from the code. If your writing a 1 man band application then pages.xml is fine. But it's absolutely useless in a large project.


                    Navigation should be handled in code. Ideally a brand new programmer should be able to start working on my application and navigate through the code and know exactly what and where the application is going. Pages.xml does not allow this.


                    I don't know exactly what the solution is, but I'm happy with the NavigationManager class we've written on our application. We don't have temporary conversations at all, but we have completely modularised our application so that no two modules share the same conversation. All modules run in their own long running conversation. (And yes we can have module x go to another instance of module x with no problems at all) We don't use the nestedConversation concept as it is ill defined. We have no navigation in pages.xml and all our our navigation can be followed in code.


                    So for instance if I want to go from module X to module Y I would make a call to moduleY.gotoModuleYPage(X parameter). My NavigationManager takes care of leaving the current conversation, starting a new conversation, executing the method (passing in the parameter). Because NavigationManager is Session scoped it is able to pass the params from one conversation to another but it doesn't have the drawback of most Session scoped beans in that it has no state. (Well it does but it's not necessary to have, I have state in it for my own application logic)


                    I would imagine that SEAM should support something like this at a much more fundamental level.


                    I should be able to annotate a method with something like


                    @NewConversation
                    public navigateToModuleY(Y param)
                    



                    And then in moduleX I should have a method like this


                    public yEntityClicked(Y y) {
                        SeamNav.navigate(YModule.class).navigateToModuleY(y);
                    }
                    



                    I know the above code doesn't work, but this is how easy it should be. And it should NOT have any strings.


                    What this code would do is that when yEntityClicked is executed it should navigate to the outcome of navigateToModuleY in a BRAND NEW conversation.


                    This would work for both TC and LRC.