5 Replies Latest reply on Oct 20, 2008 9:08 PM by David Spindle

    lesson learned mgr.find better than mgr.merge sometimes

    Dean Hiller Expert

      Maybe there is a better way(and I would be happy to hear one and change to that method).  Until then, I thought I would post my workaround to a problem I ran into.


      Let's say you have a table that list out 3 MyBeans



      id=434  edit link
      id=121  edit link
      id=765  edit link




      You then click on the edit link to edit 121 and you modify all its stuff and then you save it.  Also, if you are like me, you have an edit function that looks like so



      public void edit(MyBean bean) {
         this.bean = mgr.merge(bean); //Say the new bean has id=555
      }



      Moving on, you now click the back button until you are back to the table which has the 121 bean you clicked on(notice since you used the back button, the page does not reload the beans, so 121 bean is stale).  Now when you click edit on the 121 bean, it fails on the mgr.merge with StaleDataObjectException.  Instead of using mgr.merge here, I think you have to change to mgr.find instead.  If there is a better way, please let me know.  Just posted to help others who might run into this corner case back button issue that my QA person found.


      Hope this helps someone.


      thanks,
      Dean



        • 1. Re: lesson learned mgr.find better than mgr.merge sometimes
          Guillaume Jeudy Master

          Hey Dean,


          I'm not sure how you are setup but if you want to avoid merge(), find() you can start a long-running conversation when you initially load the 121 objects. This way these objects remain managed throughout the duration of the conversation (assuming you are using SMPC).


          In my case each edit link on the object list will start a nested conversation, if the user presses the back button and click on another object in the list the conversationId used to render the object list should be propagated on the edit link click therefore the server should be able to restore the parent conversation and get going from there.


          How are you setup ?

          • 2. Re: lesson learned mgr.find better than mgr.merge sometimes
            Dean Hiller Expert

            we DO start a long running conversation already on the edit.  The problem with merge is that when you use the back button, the script object in the list is stale from FINISHING the conversation, but if you change merge to find, it works just fine.


            ie.


            1. click edit
            2. go through long conversation and then click save MyBean
            3. click , back, back, back until you are back at the list
            4. click edit of same MyBean object
            5. RESULT if using merge: StaleObjectException
            



            LESSON:  Use find instead of merge so it loads the new object that was saved instead of using the old stale object that existed before the conversation



            Dean

            • 3. Re: lesson learned mgr.find better than mgr.merge sometimes
              Li Jihua Newbie

              Click HELP for text formatting instructions. Then edit this text and check the preview.


              Yes, i think dean is right. and it's no matter with conversiation.
              Conversiation just decide when to flush the data.

              • 4. Re: lesson learned mgr.find better than mgr.merge sometimes
                Guillaume Jeudy Master

                Dean, I think I misunderstood your usecase, so it is really about going back and editing the same object. Thanks for sharing your findings, I dont have your usecase in my app so never hit this problem before.


                By reading Seam in Action I found out more about merge() drawbacks and learnt that it should generally be avoided in favor of find() because the auto dirty checks done by the persistence context will take care of changes anyways

                • 5. Re: lesson learned mgr.find better than mgr.merge sometimes
                  David Spindle Newbie

                  I would look into using EntityHome with a long running conversation (also make sure you set flush mode to manual). 


                  I have a setup similar to yours and when I go back using the browser's back button and edit the record again, a new conversation is started and I don't get any exception.  I also get the benefit of using the Seam Application Framework classes that do a lot of things for me at the right times.


                  I'm a fan of writing less code :)


                  D