Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-171

Cascade persist update foreign key for all unchanged entities

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.0-ALPHA4
    • Fix Version/s: 2.0-ALPHA4
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      Using cascade persist, linked entities get updated even if there is no change made.

      I get an update on the unchanged foreign key even if I don't modify
      the entity at all.

      UPDATE email SET client_id = ? WHERE id = ?
      
      $query = $qb->getQuery();
      $client = $query->getSingleResult();
      $em->flush(); 
      

        Activity

        Hide
        Eric Durand-Tremblay added a comment -

        Got it! Your fix worked on OneToOne relation but not OneToMany

        I did the same test using the CmsArticles entity and here is the result :

        SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.id AS id4, c1_.topic AS topic5, c1_.text AS text6, c1_.user_id AS user_id7 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id
        FLUSH!
        UPDATE cms_users SET name = ? WHERE id = ?
        array(2) {
          [0]=>
          string(6) "FooBar"
          [1]=>
          int(17)
        }
        UPDATE cms_articles SET user_id = ? WHERE id = ?
        array(2) {
          [0]=>
          int(17)
          [1]=>
          int(2)
        }
        DONE!
        DELETE FROM cms_users_groups
        DELETE FROM cms_groups
        DELETE FROM cms_addresses
        DELETE FROM cms_phonenumbers
        DELETE FROM cms_articles
        DELETE FROM cms_users
        
        Show
        Eric Durand-Tremblay added a comment - Got it! Your fix worked on OneToOne relation but not OneToMany I did the same test using the CmsArticles entity and here is the result : SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.id AS id4, c1_.topic AS topic5, c1_.text AS text6, c1_.user_id AS user_id7 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id FLUSH! UPDATE cms_users SET name = ? WHERE id = ? array(2) { [0]=> string(6) "FooBar" [1]=> int (17) } UPDATE cms_articles SET user_id = ? WHERE id = ? array(2) { [0]=> int (17) [1]=> int (2) } DONE! DELETE FROM cms_users_groups DELETE FROM cms_groups DELETE FROM cms_addresses DELETE FROM cms_phonenumbers DELETE FROM cms_articles DELETE FROM cms_users
        Hide
        Eric Durand-Tremblay added a comment -

        Dont forget to add the cascade persist for the articles relation

        public function testFlushDoesNotIssueUnnecessaryUpdates()
            {
        
                $user = new CmsUser;
                $user->name = 'Guilherme';
                $user->username = 'gblanco';
                $user->status = 'developer';
        
                $address = new CmsAddress;
                $address->country = 'Germany';
                $address->city = 'Berlin';
                $address->zip = '12345';
        
                $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
                $article->text = "Lorem ipsum dolor sunt.";
                $article->topic = "A Test Article!";
                $article->setAuthor($user);
                $user->articles[] = $article;
        
        
                $address->user = $user;
                $user->address = $address;
        
                $this->_em->persist($user);
        
                $this->_em->flush();
                $this->_em->clear();
        
                // show SQL from here on...
                $this->_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger);
        
        
                //$query = $this->_em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.address a');
                $query = $this->_em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a');
                echo "QUERY!".PHP_EOL;
                $user2 = $query->getSingleResult();
        
                $user2->name = "FooBar";
        
                echo "FLUSH!".PHP_EOL;
                $this->_em->flush();
        
                echo "DONE!".PHP_EOL;
        
            }
        
        Show
        Eric Durand-Tremblay added a comment - Dont forget to add the cascade persist for the articles relation public function testFlushDoesNotIssueUnnecessaryUpdates() { $user = new CmsUser; $user->name = 'Guilherme'; $user->username = 'gblanco'; $user->status = 'developer'; $address = new CmsAddress; $address->country = 'Germany'; $address->city = 'Berlin'; $address->zip = '12345'; $article = new \Doctrine\Tests\Models\CMS\CmsArticle(); $article->text = "Lorem ipsum dolor sunt." ; $article->topic = "A Test Article!" ; $article->setAuthor($user); $user->articles[] = $article; $address->user = $user; $user->address = $address; $ this ->_em->persist($user); $ this ->_em->flush(); $ this ->_em->clear(); // show SQL from here on... $ this ->_em->getConnection()->getConfiguration()->setSqlLogger( new \Doctrine\DBAL\Logging\EchoSqlLogger); //$query = $ this ->_em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.address a'); $query = $ this ->_em->createQuery('select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a'); echo "QUERY!" .PHP_EOL; $user2 = $query->getSingleResult(); $user2->name = "FooBar" ; echo "FLUSH!" .PHP_EOL; $ this ->_em->flush(); echo "DONE!" .PHP_EOL; }
        Hide
        Roman S. Borschel added a comment -

        OK. I will look into this later or tomorrow.

        Thanks for your help.

        Show
        Roman S. Borschel added a comment - OK. I will look into this later or tomorrow. Thanks for your help.
        Hide
        Roman S. Borschel added a comment -

        Should be fixed now (second attempt)

        Can you check whether DDC-140 can be closed also?

        Show
        Roman S. Borschel added a comment - Should be fixed now (second attempt) Can you check whether DDC-140 can be closed also?
        Hide
        Eric Durand-Tremblay added a comment -

        Yes, this is now fixed for me.
        I confirm you this also close DDC-140

        Thank you for your great work !!

        Show
        Eric Durand-Tremblay added a comment - Yes, this is now fixed for me. I confirm you this also close DDC-140 Thank you for your great work !!

          People

          • Assignee:
            Roman S. Borschel
            Reporter:
            Eric Durand-Tremblay
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: