DDC-3375: UnitOfWork: new operation attach(): merge without persist #4170

Open
opened 2026-01-22 14:36:30 +01:00 by admin · 0 comments
Owner

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:

  • persist()
  • merge()
  • detach()

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.

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: - persist() - merge() - detach() 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.
admin added the Improvement label 2026-01-22 14:36:30 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4170