Why there is the need of detaching and merging entities in a ORM

doctrinedoctrine-ormorm

The question is about Doctrine but I think that can be extended to many ORM's.

Detach:

An entity is detached from an EntityManager and thus no longer managed
by invoking the EntityManager#detach($entity) method on it or by
cascading the detach operation to it. Changes made to the detached
entity, if any (including removal of the entity), will not be
synchronized to the database after the entity has been detached.

Merge:

Merging entities refers to the merging of (usually detached) entities
into the context of an EntityManager so that they become managed
again. To merge the state of an entity into an EntityManager use the
EntityManager#merge($entity) method. The state of the passed entity
will be merged into a managed copy of this entity and this copy will
subsequently be returned.

I understand (almost) how this works, but the question is: why one would need detaching/merging entitiies? Can you give me an example/scenario when these two operations can be used/needed?

Best Answer

When should I Detaching an entity?
Detaching an entity from the an EM (EntityManager) is widely used when you deal with more than one EM and avoid concurrency conflicts, for example:

$user= $em->find('models\User', 1);
$user->setName('Foo');

// You can not remove this user, 
// because it still attached to the first Entity Manager
$em2->remove($user);
$em2->flush();

You can not take control of $user object by $em2 because its session belongs to $em that initially load the $user from database. Them how to solve the problem above? You need to detaching the object from the original $em first:

$user= $em->find('models\User', 1);
$user->setName('Foo');

$em->detach($user);
$em2->remove($user);
$em2->flush();

When should I use merging function?
Basically when you want to update an entity:

$user= $em->find('models\User', 1);
$user->setName('Foo');

$em->merge($user);
$em->flush();  

The EM will make a compare between the $user in database vs the $user in memory. Once the EM recognize the changed fields, it only updates them and keeps the old ones.

The flush method triggers a commit and the user name will updated in the database

Related Topic