When using JPA entityManager why do you have to merge before you remove?

testing123 picture testing123 · Apr 18, 2013 · Viewed 6.9k times · Source

For a while now I have been wondering why when using JPA, do I have to write my delete methods like this:

@Transactional
public void delete(Account account)
{
    if (entityManager.contains(account))
    {
        entityManager.remove(account);
    }
    else
    {
        entityManager.remove(entityManager.merge(account));
    }
}

Perhaps the contains isn't needed since the transaction begins and ends with this method, but I still wonder why the remove couldn't just take an unmanaged object. Is it because it needs to be managed in order to know what the id is for that object? Any other insights would be great to hear. I just want to understand the hows and whys of the JPA remove.

Answer

JB Nizet picture JB Nizet · Apr 18, 2013

The remove operation can be cascaded to associations of an entity.

To be able to know which associated entities to remove, the entity manager can't rely on a detached entity, since, by definition, this detached entity doesn't reflect the latest state of the entity, and doesn't necessarily have all its cascaded associations recursively loaded.

So, if it accepted a detached entity, remove() would have to decide for you: either merge the detached entity and execute the remove operation based on what the detached entity contains, or simply load the entity having the same ID as the detached entity, and execute the operation based on the loaded entity.

Instead of deciding for you, it simply requires an attached entity. That way, you decide what you want.