3 Replies Latest reply on Nov 17, 2005 7:06 AM by Emmanuel Bernard

    Update only when EntityManager.merge() called

    Richard Wallace Newbie

      I've been reading up on EJB3 and it's entity persistence because I'm thinking of switching to EJB3 from my current Spring/Hibernate architecture. One thing I always liked about Hibernate that I never liked about JDO or some of the other ORM persistence tools is that objects are only ever persisted to the database if an update() method is explicitly called. It looks like with EJB3, if any fields of an object are changed, at the end of a transaction the database is always updated. I'd like objects to be updated in the database only when the update() method of my Dao is called. Is there a way to disable the automatic update behaviour?

      Detaching the objects from the transaction used to retrieve them would work, but then I'd lose any access to lazily loaded fields, which I don't want to do because this is going to be used primarily in a webapp and lazy loading would greatly improve performance.

      Thanks,
      Rich

        • 1. Re: Update only when EntityManager.merge() called
          Emmanuel Bernard Master

          Hibernate and eJB3 works exactly the same regarding this feature

          • 2. Re: Update only when EntityManager.merge() called
            Richard Wallace Newbie

            Oh wow. You're right, I just ran a test in Hibernate that amounted to

             session = HibernateUtil.currentSession ();
             tx = session.beginTransaction ();
            
             Game g = (Game) session.get (Game.class, games[0].getId ());
             System.out.println ("updating");
             g.setName ("Some random game");
            
             tx.commit ();
             HibernateUtil.closeSession ();
            


            And much to my chagrin it did do an update to the database, even though I didn't call session.update(g).

            Well dang it, now I'm confused. That means that if I use an Open Session In View type of pattern that anytime a user submits the form and it's successfully completed, the data will be persisted, even if the user clicked a cancel button that is merely meant to direct them to a different page.

            I guess what I really want is someway that forces the presentation layer to call the an update() method on the dao. Only then would I expect changes to be propogated to the backend. That way I can have action methods, in my JSF backing beans, like the following:

             public String update () {
             myDao.update (myObject);
             }
            
             public String cancel () {
             return "cancel";
             }
            


            The problem being that JSF will automatically update the myObject properties with whatever the user submitted. So, even if it goes to the cancel() method, the transaction will complete successfully and the changes will be persisted.

            I guess one way around this problem would be to use the immediate="true" attribute on the JSF button so the properties won't be updated when the user clicks the cancel button. Another would be to limit the scope of the transaction to the dao.get() and dao.update() methods themselves, but then I give up lazy loading of collections. I think I've also read somewhere that some people try to solve this problem using DTOs, but I don't really want to go there.

            Guess I'll have to decide what the best approach is for my situtation. Any other advice?

            Thanks,
            Rich

            • 3. Re: Update only when EntityManager.merge() called
              Emmanuel Bernard Master

              Have a look at JBoss Seam it promotes a solution to your problems