DDC-2624: ManyToManyPersister fails to handle cloned PeristentCollections #3357

Closed
doctrinebot opened this Issue Aug 20, 2013 · 7 comments

2 participants

@doctrinebot

Jira issue originally created by user bountin:

I want to clone an entity and persist the clone. The entity itself works (if I reset the identifiers to null) but a M2M collection was first ignored since I only did a shallow copy. When I do a deep copy with the following, Doctrine throws the following exception:

public function *clone()
{
if ($this->question_versions instanceof PersistentCollection) {
$this->question
versions = clone $this->question*versions;
}
}

Fatal error: Uncaught exception 'Doctrine\Common\Persistence\Mapping\MappingException' with message 'The class 'Doctrine\ORM\Persisters\ManyToManyPersister' was not found in the chain configured namespaces Foo\Entity' in /var/www/foo/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/MappingException.php on line 37

I've traced the error to the ManyToManyPersister class at the methods get{Delete,Insert}RowSQL where $coll->getOwner() is called which returns null because the owner is cleared when the collection is cloned. Therefore get_class does not work as expected under this circumstances.

I've also tried to use $coll->getTypeClass() for $class at that point but this leads to other warnings ("array key not existing" and "spl_object hash got null") and finally an SQL exception because Doctrine is inserting null as one of the identifiers.

There is a workaround for this issue but I think that this edge case should be handled too. The workaround is not to clone the collection itself but only copy the values with getValues() and let Doctrine convert it back to a collection.

@doctrinebot

Comment created by bountin:

This issue may be related to DDC-2074

@doctrinebot

Comment created by marcini:

I have the same problem on v2.4.1 after cloning collections in **clone() method of the entity, so seems that DDC-2074 didnt` fix this case. But collection cloning is needed to properly manage cloned entity relationships.

@doctrinebot

Comment created by bountin:

The getValues() workaround created some issues for us but I found another workaround. This one works for us for some time in a small to medium sized project where we heavily clone, detach and so on:

**clone() {
if ($this->m2mcoll instanceof PersistentCollection) {
$this->m2mcoll = clone $this->m2mcoll;
$this->m2mcoll->setOwner($this, $this->m2mcoll->getMapping());
}
}

The problem here is that this can not be put into the collection's clone method since it requires the entity object (which is $this).

@doctrinebot

Comment created by marcini:

Thanks Martin for your help, your workaround seems to work well in my case. I don`t know yet if it has any drawbacks that may occur in longer time period. My general thought after dealing with entity cloning is that official manual should pay more attention to this topic, because I had to figure out most of the issues by myself.

@doctrinebot

Comment created by bountin:

Yes, I've made the same experience regarding the documentation but still I haven't found time to contribute to it.
Nevertheless if you run in any problems with my new workaround, please let me know of it. (I already spent some hours in the Doctrine code for some other issues)

@doctrinebot

Comment created by @beberlei:

Fixed in 53a5a48

@doctrinebot

Issue was closed with resolution "Fixed"

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added this to the 2.4.3 milestone 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