Announcement Announcement Module
Collapse
No announcement yet.
Is that reasonable to have multiple commands ? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Is that reasonable to have multiple commands ?

    Hi ,
    l have a use case that need multi commands.
    l have one post in another thread http://forum.springframework.org/showthread.php?t=14458 , in my last post (sorting version paging) , there is a controller with many parameters input - page , pageSize , sortColumn , publisherName and ascending .

    My controller,
    Code:
    public class PublisherActions extends AbstractLibraryAction {
       private static final String PUBLISHER_FORM_OBJECT_NAME = "publisher";
       public PublisherActions() {
       setFormObjectName(PUBLISHER_FORM_OBJECT_NAME);
       setFormObjectClass(Publisher.class);
    }
    .....
    public Event SearchByName(RequestContext context) throws Exception {
    
        String publisherName = (String)context.getSourceEvent().getParameter("publisherName");
        String sortColumn = (String)context.getSourceEvent().getParameter("sortColumn");
         int page = new Long((String)context.getSourceEvent().getParameter("page")).intValue();
         int pageSize = new Long((String)context.getSourceEvent().getParameter("pageSize")).intValue();
         boolean ascending = new Boolean((String)context.getSourceEvent().getParameter("ascending")).booleanValue();
    ........
    ........
    }
    l wish to pack all the parameters (page , pageSize , sortColumn , publisherName and ascending ) into a new object called googleSortCommand.java for code readable and also for automatic binding and validation using spring service , but l suddenly realised that there is only one command are allowed in the controller, l have used it,
    Code:
    setFormObjectName(PUBLISHER_FORM_OBJECT_NAME);
    how to solve this problem ?

    moon
    Last edited by robyn; May 16th, 2006, 04:09 AM.

  • #2
    Nothing says you can only use a single FormAction in a flow. You could have 2 different FormActions, configured seperately in the application context, that handle different form (command) objects.

    Ofcourse you will no longer have the convenience of a single action backing the entire flow, but it will allow you to have multiple different form objects in a single flow.

    Erwin

    Comment


    • #3
      Hi Erwin..

      l think this is just a work around method . If l use another FormAction just for one command , then

      1. Unreasonable separate of CRUD Action . My CRUD Action will become CUD+R Actions just because l want to make a new command - googleSortCommand.java, not elegence for me.

      2. Action Numbers growth fast . Each CRUD actions have to separate from CRUD to CUD+R , what if l use a lot different pagings for some pages - simple paging , googleSort paging , ... , each need a new command , l have to make it another FormActions just for this ? this is not what MultiAction or FormAction do - my opinion. , l think except for my case , there is a lot other use case that need multiple commands support.

      Is there any good reasons not adding multiple command support ?

      moon

      Comment


      • #4
        At this moment we're not planning to enhance the FormAction to support multiple form objects out-of-the-box. However, you could quite easily build something like that yourself since, as you already noticed, FormAction is a multi-action.

        Erwin

        Comment


        • #5
          How easy can l add a multiple command support myself ? can you give some hint ?

          moon

          Comment


          • #6
            How about we make the command , validator dynamic , inject the command and validator when we needed in the flow?
            (We have to inject the formObjectName , formObjectClass , formObjectScopeAsString , validator at runtime)

            Something like below ,

            Code:
            <action-state id="bindAndValidate.SaveForm">
                <action bean="publisherActions" method="bindAndValidate" commandName="XXXcommand" commandClass="XXX.class" Scope="XXXScope" validator="XXXValidator"/>
                    <transition on="success" to="Save"/>
                    <transition on="error" to="formView"/>
            </action-state>
            do the injections in the flow (xxx-flow.xml), not the beginning of the application (xxx-servlet.xml) , do it before binding , is that possible ?
            if this is possible , then we don't have to change too much code...hihi

            moon

            Comment


            • #7
              You could do something like that using action properties that a custom FormAction subclass processes.

              Code:
              <action-state id="bindAndValidate.SaveForm"> 
                  <action bean="publisherActions" method="bindAndValidate">
                      <property name="commandName" value="XXXcommand"/>
                      <property name="commandClass" value="XXX.class"/>
                      <property name="scope" value="XXXScope"/>
                      <property name="validator" value="XXXValidator"/>
                  </action> 
                  <transition on="success" to="Save"/> 
                  <transition on="error" to="formView"/> 
              </action-state>
              Check the DTD for details.

              Erwin

              Comment


              • #8
                ... thanks for the hint.

                l have not try yet , but it seems to have a "dynamic" command now ....hihihi . But , if we do it this way , we are changing the state of an action .
                We must be careful when we are changing a singleton action's state , "is it thread safe ?" -- the first question arise into my head , the answer seem to be "no" for my case. Even though l success to set the command , validator and scope dynamically , Client 1 will interfere with Client 2.

                For example , If l do it this way,
                (C,R,U,D are all methods in PublisherActions.java)

                1. set command 1(Publisher.class) , validator 1(PublisherValidator) in xxx-servlet.xml for C,U,D methods in PublisherActions.

                2. set command 2(GoogleSortCommand) , validator 2(GoogleSortValidator) dynamically in xxx-flow.xml for method R in PublisherActions. (as previuos code post in this thread by Erwin)

                When Client 1 call method R , then PublisherActions's state will change to (command2,validator2,..) instead of (command1,validator1,..) , it will cause problem for Client 2 when he call any methods C,U,D --> because Client 2 need state (command1,validator1,..) , not (command2,validator2,..) , unless we change those variable (command , validator ,...) to threadlocal variable in FormAction, , right ?

                if this can work , then we solve the problem of multiple commands problem. Is my idea work ? hihi ....just an imagination ...

                Remark :

                My "multiple command" problem here is just a single command for each actions (each methods) , and not multiple commands for each actions (each methods). Somebody will misunderstand it easily...

                moon

                Comment


                • #9
                  Obviously you would indeed have to look out for threading issues, so you can't directly use FormAction. ThreadLocals seem inappropriate since they will be difficult to clean up. I suggest you try to write a special FormAction that does not hold the formObjectClass and formObjectName in member variables, but always takes them from action execution properties. That way you could avoid the concurrency issues since your special FormAction would basically be stateless.

                  Erwin

                  Comment


                  • #10
                    Yes , indeed , threadlocal not a good idea .

                    l saw a post "ThreadLocals are EVIL!!!" by Alef Arendsen in http://blog.arendsen.net/ .

                    If threadlocal not a way to do multiple commands , then how to do multi-commands without using another FormAction ? these seem not so easy...hihi
                    These problem are so familiar for me . Erwin , do you remember l ask the "just in time successView ..." question b4 ? http://forum.springframework.org/showthread.php?t=13765 , we are in the same situation now . At that time , l want to inject a successView into the SearchProductsController , but now , l wanna to inject another command into my FormAction -- PublisherActions... At that time , you suggest a low tech method to solve my problem , but it will cause thread problem too , because the controller is a singleton , not prototype .

                    Why we have these hard feeling ? Because our controllers are mostly singleton ? Ok , since we came to singleton again , l would like to discuss further about singleton . Why our controllers are mostly singleton ? because we don't want too many instances ? yes , that is our main purpose to make it a singleton , but what it looks like after it became a singleton , Oh .. like "dead object" , even it has state . What is "dead object" mean ? "dead object" means the object have fixed state , we cannot change it once it is initialized , otherwise it will cause thread problem as l mention above. Spring seems to promote us to use singleton if possible , so a lot of our controllers are singleton. Then l saw a lot "dead object" here in our applications , because we use a lot "dead objects" . The springframework MVC part are more easy to implement if we use mostly "dead object" , but it will lost the flexibility for a framework should have ... ( this is not a criticism , l don't know even l opinion above right or wrong ...haha.. just want discussion)

                    But what if l need to change my controller state for some reasons ? Oh ...since threadlocal is not a good idea , you have to make them (those controllers) a prototype ? As Webwork did to their controllers , all prototype . Webwork are not suffer the hard feeling here , every clients free to change their controllers state , because they are all prototype.

                    So singleton are not good ? if we refer the spring doc version 1.2RC2 , pg23 , we have "Spring cannot manage the complete lifecycle of a non-singleton/prototype bean"
                    Important note: when deploying a bean in the prototype mode, the lifecycle of the bean changes slightly. By
                    definition, Spring cannot manage the complete lifecycle of a non-singleton/prototype bean, since after it is
                    created, it is given to the client and the container does not keep track of it at all any longer. You can think of
                    Spring's role when talking about a non-singleton/prototype bean as a replacement for the 'new' operator. Any
                    lifecycle aspects past that point have to be handled by the client. The lifecycle of a bean in the BeanFactory is
                    further described in Section 3.4.1, “Lifecycle interfaces”.
                    Actually l don't know what is Lifecycle of a bean means , it seem important and emphasized many times from docs.

                    How to implement a multiple commands model to FormAction ? l am back to the original place ...hihihi ...l also saw another post by the same author Alef Arendsen - "Spring MultipleCommandController revisited" in the same blog as above , it seem that the Spring people inside also thinking about this problem.

                    -------------------------------------------------------------------------------------------------------------------------------------------------------
                    Beside the above blur blur blur ...hihi...l am not understand the below 2,
                    I suggest you try to write a special FormAction that does not hold the formObjectClass and formObjectName in member variables, but always takes them from action execution properties. That way you could avoid the concurrency issues since your special FormAction would basically be stateless.
                    you mean we use
                    Code:
                    <action-state id="bindAndValidate.SaveForm"> 
                        <action bean="publisherActions" method="bindAndValidate"> 
                            <property name="commandName" value="XXXcommand"/> 
                            <property name="commandClass" value="XXX.class"/> 
                            <property name="scope" value="XXXScope"/> 
                            <property name="validator" value="XXXValidator"/> 
                        </action> 
                        <transition on="success" to="Save"/> 
                        <transition on="error" to="formView"/> 
                    </action-state>
                    to set the properties at runtime each time ? (l tried b4 , but failed to set the properties at runtime , just a fast try)

                    Thanks

                    moon
                    Last edited by robyn; May 16th, 2006, 03:56 AM.

                    Comment


                    • #11
                      Actually l don't know what is Lifecycle of a bean means
                      The bean lifecycle methods are those of the InitializingBean and DisposableBean interfaces.

                      you mean we use ... to set the properties at runtime each time ?
                      Exactly.

                      Erwin

                      Comment


                      • #12
                        The bean lifecycle methods are those of the InitializingBean and DisposableBean interfaces.
                        yes , l knew that . But what is that mean ? why it is important for the container to manage the complete lifecycle of a non-singleton/prototype bean , what happen if l don't do that ? any downside ? l cannot find the reason in the docs...

                        moon

                        Comment

                        Working...
                        X