mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
DDC-3375: UnitOfWork: new operation attach(): merge without persist #4171
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @doctrinebot on GitHub (Nov 6, 2014).
Originally assigned to: @Ocramius on GitHub.
Jira issue originally created by user mathieudz:
Currently UnitOfWork provides the following three methods that make entities cross the boundaries of being managed or not:
In my opinion, there's an operation missing: attach(). It would be similar to merge(), but it would not call persist(). It would be the counterpart of detach().
Example 1: Simple case
{quote}
if (...)
$person = new Person;
else
$person = $em->find('Person', $id);
// At some point I decide that I don't want to store the person, so I don't call persist()
$dog = new Dog;
$em->persist($dog);
$em->flush(); // OK, commits only the dog
{quote}
Example 2: Same, but the person is serialized along the way
{quote}
if (...)
$person = new Person;
else
$person = $em->find('Person', $id);
// Serialize the person
$serializedPerson = serialize($person);
// At some point I want to restore the person
$person = unserialize($serializedPerson);
// Because it could have been a managed entity before, I need to merge it.
$person = $em->merge($person);
// But yet again, I decide that I don't want to store the person, so I don't call persist()
$dog = new Dog;
$em->persist($dog);
$em->flush(); // Oops, if the person was NEW, it has become managed, so it is commited now!
{quote}
If merge() was replaced by attach(), flush() would not have commited the person.
@doctrinebot commented on GitHub (Nov 6, 2014):
Comment created by stof:
I don't understand what attach would do in your case. flush is about flushing the whole unit of work. I don't understand what attach() would do if it does not attach the entity to the unit of work.
@doctrinebot commented on GitHub (Nov 6, 2014):
Comment created by stof:
And actually, the opposite of detach() already exists: it is persist(). It makes the object enter the unit of work, while detach makes it leave the unit of work.
Note that merge is not making the object cross the boundary. The object passed to merge() never enters the unit of work. what happens is that the data inside this object are applied to an object inside the boundary (potentially a new one if there was no object with this identifier).
When using merge, you are explicitly asking to apply the data inside the unit of work, so it is logical that something gets flushed.
and note that in your example 1, your person is managed half of the time (when coming from find() rather than a new instance). And in such case, it will be flushed. You are not flushing only the dog.
@doctrinebot commented on GitHub (Nov 7, 2014):
Issue was closed with resolution "Won't Fix"
@doctrinebot commented on GitHub (Nov 8, 2014):
Comment created by mathieudz:
OK, makes sense.