DDC-2701: Collections in originalEntityData gets over written #3443

Closed
doctrinebot opened this Issue Sep 23, 2013 · 8 comments

2 participants

@doctrinebot

Jira issue originally created by user tklein:

I was trying to use the UnitOfWork::getOriginalEntityData method and i noticed that if there is a collection in that object, it changes in the uow original datas when i change it on my original object

In my case the collection is ManyToMany unidirectional

I think this happens because both the uow and the object work with the same reference to the collection
maybe adding a clone of the collection instead of the real one, i don't know if it is possible

Thank you for taking a look and for Doctrine!

Tom

@doctrinebot

Comment created by @ocramius:

This issue needs a test case in order to be reproduced.

@doctrinebot

Comment created by tklein:

Here is how i get to this bug:

2 entities with a many to many unidirectional relation:

class Conversation
{
    // ...........

    /****
     * @ORM\ManyToMany(targetEntity="User")
     * @ORM\JoinTable(name="Conversations*To*Users",
     *      joinColumns={@ORM\JoinColumn(name="conversation_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}
     * )
     *
     * @var ArrayCollection
     */
    private $users;

    public function getUsers()
    {
        return $this->users();
    }

    // .....
}

class User
{
    // .....
}

Load the Conversation entity joined with the associated users: you get a Conversation entity with the users property filled with a PersistentCollection initialized. You can find this object in the originalEntityData property of the unit of work.

Then do:

$users = $conversation->getUsers();
$users->remove(0);

In the conversation object, the first user of the collection has been removed. In the unit of work, find the corresponding object in the originalEntityData array and you'll see that the first user has been removed from the collection too. It is then not possible to use the originalEntityData on joined collection to check for changes

@doctrinebot

Comment created by @ocramius:

[~tklein] still not sure what the problem is:

$user         = new User();
$conversation = new Conversation();

$conversation->addUser($user);

$em->persist($user);
$em->persist($conversation);
$em->flush();
$em->clear();

$conversation1   = $em->find('Conversation', $conversation->id);
$usersCollection = $conversation->getUsers();

$usersCollection->remove(0);

var_dump($em->getUnitOfWork()->getOriginalEntityData($conversation1));

// what is failing after this point?

This is also how a test case should look like when thrown at the ORM functional test suite: https://github.com/doctrine/doctrine2/tree/v2.4.4/tests/Doctrine/Tests/ORM/Functional/Ticket

@doctrinebot

Comment created by tklein:

Sorry i'll try to write a real test case asap ...

What is failing after this point ?

$origConversationData = $em->getUnitOfWork()->getOriginalEntityData($conversation1);
var_dump(count($origConversationData['users'])); // should be equal to 1, i get 0 ...

The only diff i can see with your example is that i'm not using find but a query with the relation fetched-joined in it so the collection is initialized

@doctrinebot

Comment created by @ocramius:

Collections are not tracked within entity data, but separately in the UoW

@doctrinebot

Comment created by tklein:

Ok so i guess we can close this ticket if this is an expected behavior ...

In your last comment, did you mean:
Collections are not tracked within entity data, but each element of the collection is tracked separately in the UoW ?

Anyway thanks for your help

@doctrinebot

Comment created by @ocramius:

I mean that collections are tracked by specific properties/states in the UoW: https://github.com/doctrine/doctrine2/blob/9bf8f6ed4cc6590def5b5e8ba739ecdfa62fb717/lib/Doctrine/ORM/UnitOfWork.php#L180-L192

Yes, collection items are still single entities tracked in the UoW

@doctrinebot

Issue was closed with resolution "Invalid"

@Ocramius Ocramius was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment