5 Replies Latest reply on May 31, 2009 11:07 AM by Konstantin Konstantinopel

    Understanding how to implement an atomic web transaction with Seam

    Konstantin Konstantinopel Newbie

      Hi Seam Users!


      After I've got running the Seam Managed Persistence Context (SMPC) described  here, I don't understand really how to implement an atomic web transaction with Seam.


      My situation is the following: I've an conversation with three pages (a wizard) where I make different changes on different objects. On the last page I want to commit all changes or discard all changes.


      I've tried it like this: On the first page I've started an conversation with flush mode set on MANUAL and on the last page, I've made an em.flush(). But at the first occurs of em.merge() the object was written to the database although no em.flush() was called.


      What's the reason for this? My understanding is, that nothing is written to the database before em.flush was called. Isn't it? Does em.merge() writes the object directly the database although flush mode is set on MANUAL? For me, it is not very transaction like.


      Can anyone verify this behavior? Or have I made an mistake?


      Cornelius

        • 1. Re: Understanding how to implement an atomic web transaction with Seam
          Jean Luc Apprentice

          One comment: with an extended persistence context you should not need to use merge(), the whole idea of an extended PC is to avoid that call. The changes accummulate in the Java object during the wizard which, at the end signalled by flush(), are persisted to the db. There is no intermediate merge() - that's the behaviour Seam tries to avoid.


          • 2. Re: Understanding how to implement an atomic web transaction with Seam
            Adrian Mitev Master

            And here is a whole article on
            When - and when not - to use the JPA merge method
            .

            • 3. Re: Understanding how to implement an atomic web transaction with Seam
              Konstantin Konstantinopel Newbie

              Jean and Adrian, thanks for your help. I've understood this and it sounds logically.


              But in my situation I want to add a new object in this wizard. Before rendering the first page I initialize a new entity. During the conversation I want to add and modify      several entities. At the end of conversation I want to decide whether the modifications should transfered to the database or not.


              What is the best practice for this intention? Does my application have to keep in mind which should be added via em.persist(...) before em.flush() to do this at the end of transaction? It sounds not very comfortable.


              The main question is: How can I add an entity to the persistence context without writing the entity directly to the database?


              Cornelius

              • 4. Re: Understanding how to implement an atomic web transaction with Seam
                Jean Luc Apprentice

                Adding an entity to a context (i.e. making a transient entity persistent) is done via persist() and this operation only causes an immediate real write to the db (as opposed to one delayed until the flush) if the id of the entity is generated at insert-time. This is because persist() is required to return that id. When using Oracle sequences, for instance, there is no need for an immediate write because the JPA provider can read the next value from the sequence separate from the writing of the entity. With other id generation schemes, however (such as databases with auto-increment fields), a write operation is needed.


                Which database and id generator are you using/

                • 5. Re: Understanding how to implement an atomic web transaction with Seam
                  Konstantin Konstantinopel Newbie

                  Jean Luc wrote on May 31, 2009 07:21:


                  Adding an entity to a context (i.e. making a transient entity persistent) is done via persist() and this operation only causes an immediate real write to the db (as opposed to one delayed until the flush) if the id of the entity is generated at insert-time. This is because persist() is required to return that id. When using Oracle sequences, for instance, there is no need for an immediate write because the JPA provider can read the next value from the sequence separate from the writing of the entity. With other id generation schemes, however (such as databases with auto-increment fields), a write operation is needed.


                  Yes! This is the solution for my problem!



                  Jean Luc wrote on May 31, 2009 07:21:


                  Which database and id generator are you using/


                  I'm using a MySQL database during development. I haven't specified a GenerationType (which means auto, I think.) I've changed the GenerationType to Table and it works like I want! (Sadly, MySQL doesn't support sequences.)



                  Thank you very much for your help!


                  Cornelius