6 Replies Latest reply on Feb 27, 2008 3:11 AM by luxspes

    One Conversation to rule all Crud

    franciscoperedo

      Hi!
      I used seam-gen to generate an entiry crud application, now, I add 3 buttons in home.seam with names begin transaction, commit transaction, rollback transaction.


      What do I want to achieve with this?


      If the user hits begin transaction from that poin on, everything should run in the same transaction: the user should be able to enter any of the CRUD pages and do whatever he wants.


      If at the end, he/she believes the changes que made are good, que returns to the home.seam page and clicks commit transaction and the trasaction is commited.


      On the other hand, if he doesn't like the changes, he can also return to home.seam and hit  rollback transaction and the big rule all transaction should rollback and everything should go back to the way it was.


      Am I crazy to thing this would be a good job for Seam's conversation-scoped extended persistence context ?


      where should I start? I tried adding this class:


      Name("startHome")
      @Scope(ScopeType.CONVERSATION)
      public class StartHome {
      
           
           @In EntityManager entityManager;
           
           @Begin(flushMode=FlushModeType.MANUAL,join=true)
           public void beginTransaction(){          
           }
           
           @End
           public void endTransaction(){
                this.entityManager.flush();
           }
           
           
           public void rollbackTransaction(){
                throw new RollbackException();
           }
           
           @Destroy
           public void destroy(){}
           @Remove
           public void remove(){}
      }
      
      
      



      and bindig it to the 3 buttons I added to the home.seam page in this way:


      <h:commandButton value="Begin Conversation" action="#{startHome.beginTransaction}"/>
      }
      



      The methods get called, but they have no effect.
      Any hints on what should I do?


        • 1. Re: One Conversation to rule all Crud
          pmuir

          Switch your SMPC to MANUAL flush mode, and do it all in a single conversation? I can't think of a better way to do this... Or, I guess, make your PC session scoped, and use MANUAL flush mode.

          • 2. Re: One Conversation to rule all Crud
            franciscoperedo

            Hi! Thanks for answering!
            Okey, first, I realized I needed an EAR projecto to use conversation-scoped extended persistence context (is that what you mean by SMPC?)
            So, now my project is an EAR project.
            Next I realized I needed to make my StartHome class an Stateful EJB, and add a @Local interface:


            @Name("startHome")
            @Scope(ScopeType.CONVERSATION)
            @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)
            @Stateful
            public class StartHome implements IStartHome {
            
                 
                 @PersistenceContext(type=PersistenceContextType.EXTENDED)
                 EntityManager entityManager;
                 
                 
                 @Begin(flushMode=FlushModeType.MANUAL,join=true)
                 public void beginTransaction(){          
                 }
                 
                 
                 @End
                 public void endTransaction(){
                      this.entityManager.flush();
                 }
                 
                      
                 public void rollbackTransaction(){
                      throw new RollbackException();
                 }
                 
                 @Destroy
                 public void destroy(){}
                 @Remove
                 public void remove(){}
            }
            



            @Local
            public interface IStartHome {
                 
                 public abstract void beginTransaction();
                 
                 public abstract void endTransaction();
            
                 public abstract void rollbackTransaction();
            
            }
            



            Then I realized that the links in the menu reset the converstion,  so I modified them to stop doing that...


            <s:link view="/${entity.shortName}List.xhtml" 
                        value="${entity.shortName} List" 
                  propagation="none"/>
            



            So i removed the none propagation...


            Then I realized that the ${entity.shortName}List.page.xml end the conversations:


            <end-conversation/>
            



            So I removed that too...


            So now, I start the aplication, push the begin trasaction/conversation button in home.seam, go to one of my entities, create a new pojo/row, save it, go back to home.seam click rollback transaction (of course my exception RollbackException is annotated with javax.ejb.ApplicationException and the rollback property equals true) , and the pojo should dissapear...


            It doesn't dissapear!!!!!!


            If the converstion has not ended... and I throw an exception annotated for rollback... shouldn't all my changes be rollbacked?


            Is there a way to ask Seam to give more information on how the transactions are being handled?


            Any hints on what am I doing wrong? Do i need to make each of the automatically generaed Homes of each of my entities an Stateful bean? and... do I have to tell them to use tne EXTENDED persistency type? how do I do that?




            • 3. Re: One Conversation to rule all Crud
              nickarls

              I'm not quite sure of what you are saying but...


              No matter what you do with the transaction after the addition of the new pojo and saving (rollback or commit), the conversation scope pojo as a model will still stick around until you end the conversation and start a new one.


              When you say the pojo doesn't disappear, are you sure the current conversation ends and a new starts?

              • 4. Re: One Conversation to rule all Crud
                franciscoperedo

                Hi! Thanks for answering.
                How can I be sure the conversation ends? After I trigger the exception, I just stop Jboss and I start it again, if the rollback did its job, the new pojo should be gone... but it is not...


                My objective is to wrap all the CRUD seam generated pages in single conversation, and:


                If I end the conversation by calling startHome.endTransaction() the
                data is commited and the conversation ends.


                If I end the conversation by calling startHome.rollbackTransaction() an exception is thrown that should rollback all the CRUD changes and end the conversation.


                That's it... sounds easy... but I can not make it work... (BTW the only framework that ever used that made this easy was WebObjects, I really hope Seam takes me to an even higher state of productiveness, but I am starting to feel a little worried)


                Regards,


                Francisco

                • 5. Re: One Conversation to rule all Crud
                  franciscoperedo

                  Hi!


                  Just to be more clear, when I say a single conversation I mean a single one until I say otherwise by ending it commit or in rollback, this should allow me to enter the CRUD pages of Entity A do all kinds of CRUD stuff, then do the same with Entity B, then with Entity C, and then, rollback (or commit) all the changes to A, B and C with a single click.


                  Regards,
                  Francisco

                  • 6. Re: One Conversation to rule all Crud

                    Mmmmm... I feel like I don't explain myself correctly... mmmm,
                    lets put it this way:


                    Basically, what I would like is to have a kind of sandbox, so that the user feels that he can safely Create Update or Delete information of any table, in any order, create relationships between different pojos or break those relationships, and, if, at the end, he hits a save all changes button, then everything gets commited... and if he hits cancel all changes then, everything is rollbacked, as if nothing happened...


                    In other words... full UnitOfWork support.


                    Anyone here has tried to add this functionality to the CRUD generated by seam-gen?


                    Thanks
                    Regards,
                    LuxSpes