2 Replies Latest reply on May 16, 2007 4:03 AM by Chris Lowe

    Confusion over em.refresh()?

    Chris Lowe Apprentice

      Hello All,

      I'm working on a Seam/EJB3 app where I have a persisted object that I am editing. The object has a many-to-one set, to which the user can add newly created objects via the UI. If the user adds an object and chooses "ok" to persist their changes then all is well, the new object gets persisted just fine. The problem I am having is when the user chooses "Cancel". Rather than unpicking their changes, I wanted to simply call em.refresh(obj) to reset the object back to the previous state, however I get the following exception when I try this:

      No row with the given identifier exists: [com.example.model.Address#0]
      at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
       at org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:269)
       at org.jboss.ejb3.entity.ExtendedEntityManager.refresh(ExtendedEntityManager.java:154)
       at org.jboss.seam.persistence.EntityManagerProxy.refresh(EntityManagerProxy.java:133)


      So, it looks like the EM has tried to refresh one of the newly created child objects rather simply restoring the object's many-to-one set.

      If I call obj.getAddresses().clear() prior to calling refresh() then it succeeds. I get my object with the previous state.

      My (simplistic?) expectation of refresh was that I could call it regardless of the state I manage to get the object into and it will revert it back to the state of the database. Should this be the case?

      Cheers,

      Chris.

        • 1. Re: Confusion over em.refresh()?
          fhh Expert

          Have you annotated the collection with CascadeType.REFRESH?

          Regards

          Felix

          • 2. Re: Confusion over em.refresh()?
            Chris Lowe Apprentice

            Hi Felix,

            Success!

            Firstly apologies, I wrote "many-to-one" in my post. It is actually OneToMany (was quite late when I was writing ;)

            On my collection I had specified CascadeType.ALL which includes CascadeType.REFRESH.

            @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "order")
             public Set<Address> getAddresses() {
             return this.addresses;
             }


            Changing this to exclude REFRESH worked a treat!

            @OneToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY, mappedBy = "order")
             public Set<Address> getAddresses() {
             return this.addresses;
             }


            All my entities are code generated, which I suppose makes it easy to overlook some of the finer details.

            Thanks for your help - greatly appreciated.

            Chris.