1

I am using JPA (with Hibernate as the JPA provider). I have an operation to remove an entity, and it seems that if I detach the entity and immediately merge it an exception is thrown, i.e.

em.find(entity.class, entitiy.getId())
em.detach(entity)
em.merge(entity)   

will cause errors while simply

em.find(entity.class, entitiy.getId())

Will pass flawlessly. Is there something that I am missing regarding detach and merge? I didn't do anything on the entity itself, it wasn't change, so the merge should not change anything.

I can elaborate more on my specific case if needed.

EDIT

As @rmertins pointed out, I should have used the return value from the merge, as merge returns the merge entity while the entity we have used as a parameter stays detached. This works:

em.find(entity.class, entitiy.getId())
em.detach(entity)
entity = em.merge(entity)  
apines
  • 1,254
  • 14
  • 36
  • 3
    errors ? care to give people a clue, like the exception? – Neil Stockton Nov 10 '14 at 11:53
  • Is `entity` class or Object? – Yubaraj Nov 10 '14 at 11:54
  • EntityNotFoundException for another entity that was removed (prior to invoking the em.find(), still in the same transaction). I said I'll elaborate more if needed :) Entity is an object, entity.class should be Entity.class). – apines Nov 10 '14 at 12:14
  • Am I understanding you correctly? You are getting an EntityNotFoundException on your call to em.merge? That would be more that strange. – kostja Nov 10 '14 at 12:43

2 Answers2

2

Is it that you still use the old entity reference instead of the one returned by merge?

The merge operation doesn't reattach the given entity. The merge operation looks for an already loaded entity and since it cannot find one (because you detached it) it loads the entity from the database and it copies the supplied entity data onto the fresh copy from the database.

If you do something like this:

MyEntity myEntity = em.find(MyEntity.class, myEntity.getId())
em.detach(myEntity);
em.merge(myEntity);

Then you simply discard the actual merged entity because you don't reassign myEntity to the merge result. You should do this instead:

myEntity = em.merge(myEntity);

Now myEntity will reference an attached entity (an entity loaded in the 1st Level Cache a.k.a Persistence Context).

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
1

Sorry my fault, was to fast.

Look here, very good explanation:

http://blog.xebia.com/2009/03/23/jpa-implementation-patterns-saving-detached-entities/

Here is the sentence that matters:

That means that after invoking EntityManager.merge, we have to use the entity reference returned from that method in place of the original object passed in.

So the clue is that after merge your entity object is still detached, but the resulting object copy from merge is attached to the persistence context again.

Rene M.
  • 2,660
  • 15
  • 24
  • That's it! Can't believe I didn't try this one, missed the return value of merge(), thanks! – apines Nov 10 '14 at 14:54