3 Replies Latest reply on Feb 15, 2007 12:11 AM by mazz

    Not understanding detached entities and merge()

    smokingapipe

      Here's the situation:

      I have an entity that refers to other entities, like this:

      @Entity public class Invoice implements Serializable {
       @ManyToOne private transient Customer customer;
      }


      It must implement Serializable so I can send it to message queues.

      I labeled the customer field as transient, because I don't want it to serialize and send the entire Customer object every time (that object has a bunch of its own fields).

      So, because that's transient, this Invoice entity shows up, is de-seriaiized, and the customer field is null of course.

      I then do

      invoice = entityManager.merge(invoice);


      to re-attach this now-detached entity. But when I do that, the customer field gets set to null in the DB. It is taking the state from the un-serialized object and writing over what's in the DB.

      That's not what I want it to do, of course.

      What's the right way to do this kind of thing? An easy work around I have is to use entityManager.find(Invoice.class, invoice.getId()) but that seems wrong.

      Ideas?


        • 1. Re: Not understanding detached entities and merge()
          mazz

          The behavior you are seeing with "merge" is correct. It takes a detached entity and merges it into the DB.

          • 2. Re: Not understanding detached entities and merge()
            smokingapipe

            So what do I want to use to re-attach a detached entity? I think in Hibernate I would use session.refresh(entity). What would it be in EJB3?

            • 3. Re: Not understanding detached entities and merge()
              mazz

              You do as you originally said - that is, use find() to load in the entity and fill in that attached entity with the data coming in from that detached pojo.

              There isn't much you can do because the detached pojo you are getting is half-full (i.e. missing that transient data). It has some data but not all of it; but the JPA container doesn't know what is "right" and what is "wrong" with respect to the contents of your detached pojo (since a null collection is clearly a valid thing to have - the container doesn't know if that's what you really want or not). The merge(), therefore, is going to assume the detached pojo getting merged is "full" - that is, it has the correct state for the entire entity.