Symfony2 and Doctrine: OneToMany relation duplicates data in the table

doctrine-orm, entity, php, sql, symfony

Solution

I didn't caught your problem before I reproduced it but now it's a kind of obvious. Your problem comes from the use of the clear method. Actually, if you clear your entity manager, it forgets their existence and will persist them as new ones.

If you have performance issue, you can limit the number of items you deal with and do it recursively until you're done.

I hope it helped you ;)

Good Luck

Cheers

Problem

I have two tables: articles and emails. The emails table will contain emails related to the specific articles, for example: ``` id | article_id | email 1 | 1 | test@etest.com 2 | 1 | test2@test.com 3 | 2 | test@etest.com 4 | 2 | test3@test.com ``` Etc.... There is a relation between article_id and the id from the articles table. In my entity, I have this code: ``` class Articles { .... /** * @ORM\OneToMany(targetEntity="\Acme\DemoBundle\Entity\Emails", mappedBy="articles") */ private $emails_rel; ... } class Emails { /** * @ORM\ManyToOne(targetEntity="\Acme\DemoBundle\Entity\Articles", inversedBy="emails_rel", cascade={"all"}) * @ORM\JoinColumn(name="article_id", referencedColumnName="id") **/ private $articles; } ``` In my controller, i am doing some tests where I will persist or not some entities. At the end, I am doing a flush ``` $em->flush(); ``` And the strange behaviour is that in my Emails table, the data is duplicated as soon as I am doing the flush. When testing the entity manager with ``` $em->getUnitOfWork()->getScheduledEntityInsertions() ``` I am getting an empty array. Any idea why? Thank you very much. EDIT: Here is the test: ``` $articl = new Articles(); $articl = $em->createQuery("SELECT p FROM Acme\DemoBundle\Entity\Articles p WHERE p.bMailToMatch = 1")->getResult(); $nb = count($articl); // BECAUSE I WILL WORK WITH A LOTS OF ENTRIES - PREVENT MEMORY OVERFLOW $em->clear(); if(isset( $articl )) { foreach($articl as $i => $art) { $array_emails = null; $art_emails = $art->getEmailsRel(); foreach ($art_emails as $e) { $array_emails[] = $e->getEmail(); } $art_id = $art->getId (); echo "\n\n---------- $i ----------\n " . $art->getDoi (); // TAKES ARTICLE WITH ZERO EMAIL if (!isset($array_emails) ) { $updated_article = $em->getRepository('AcmeDemoBundle:Articles')->findOneBy(array( 'id' => ($art_id) )) ; // Because of the clearing of the entity manager echo"\n\n$art_id Article DOI \n".$updated_article->getDoi(); echo "\n==>Put the BMailToMatch's flag to 0"; $updated_article->setBMailToMatch(0); $em->persist($updated_article); } else { echo " ==> ok\n"; } if (($i % 3) == 0) { $em->flush(); $em->clear(); } } $em->flush(); $em->clear(); } return new Response ( "\n\nFinished!!\n" ); ```

Original source