Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-2996

UnitOfWork::recomputeSingleEntityChangeSet() will not add a new change set

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.5, 2.4.3
    • Component/s: None
    • Security Level: All
    • Labels:
      None

      Description

      I have noticed something weird in the UnitOfWork::recomputeSingleEntityChangeSet() and I suspect it is a bug.

      If I write a Listener that, on the onFlush() event, changes an entity: the documentation says to call "recomputeSingleEntityChangeSet()". However, in that method, if a change set DOESN'T EXIST, then no changeset seems to be set at all: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L940

              if ($changeSet) {
                  if (isset($this->entityChangeSets[$oid])) {
                      $this->entityChangeSets[$oid] = array_merge($this->entityChangeSets[$oid], $changeSet);
                  }
      
                  $this->originalEntityData[$oid] = $actualData;
              }
      

      As you can see, if a changeset exist, we merge it, but there is no "else".

      That "bug" would be consistent with a problem I'm facing: calling recomputeSingleEntityChangeSet() in onFlush() on an entity that previously (at the time of the flush) had no changes, then that entity's changes are not persisted.

      Related: people saying recomputeSingleEntityChangeSet() doesn't work (just like me):

      So it is a bug? Or is it intended?

        Issue Links

          Activity

          Hide
          Benjamin Eberlei added a comment -

          Fixed

          Show
          Benjamin Eberlei added a comment - Fixed
          Hide
          Matthieu Napoli added a comment -

          Awesome news thanks

          Show
          Matthieu Napoli added a comment - Awesome news thanks
          Hide
          Vitaliy Zhuk added a comment -

          I have a problem after update with this commit.
          My application control entity insertions/updated and change another field in entity.

          Logic example:

          Check each entity in insertions
          Check each entity in updated
          

          And i call recompute change set in entity in check insertion, this entity added to updated, and the second step not good working, because entity INSERTIONS!

          Subscriber, for example:

          <?php
          
          namespace Acme\DemoBundle\EventListener\Doctrine;
          
          use Acme\DemoBundle\Entity\Top;
          use Doctrine\Common\EventSubscriber;
          use Doctrine\ORM\Event\OnFlushEventArgs;
          use Doctrine\ORM\Events;
          
          class TopChangedSubscriber implements EventSubscriber
          {
              /**
               * On flush event
               *
               * @param OnFlushEventArgs $event
               */
              public function onFlush(OnFlushEventArgs $event)
              {
                  $em = $event->getEntityManager();
                  $uow = $em->getUnitOfWork();
          
                  $topMetadata = $em->getClassMetadata('DemoBundle:Top');
          
                  foreach ($uow->getScheduledEntityInsertions() as $top) {
                      if ($top instanceof Top) {
                          $top->setChanged(301 -  $top->getPosition());
           
                          // So, i call to recompute, because entity changed.
                          // BUG #1? This entity added to entity updates, and getScheduledEntityUpdates returned incorrect data
                          // BUG #2? This entity has been insert (1 SQL query) and update (2 SQL query)!
                          $uow->recomputeSingleEntityChangeSet($topMetadata, $top);
                      }
                  }
          
                  foreach ($uow->getScheduledEntityUpdates() as $top) {
                      if ($top instanceof Top) {
                          $changes = $uow->getEntityChangeSet($top);
          
                          if (isset($changes['position'])) {
                              list ($oldPosition, $newPosition) = $changes['position'];
          
                              $top->setChanged($oldPosition - $newPosition);
          
                              $uow->recomputeSingleEntityChangeSet($topMetadata, $top);
                          }
                      }
                  }
              }
          
              /**
               * {@inheritDoc}
               */
              public function getSubscribedEvents()
              {
                  return array(Events::onFlush);
              }
          }
          

          Thank.

          Show
          Vitaliy Zhuk added a comment - I have a problem after update with this commit. My application control entity insertions/updated and change another field in entity. Logic example: Check each entity in insertions Check each entity in updated And i call recompute change set in entity in check insertion, this entity added to updated, and the second step not good working, because entity INSERTIONS! Subscriber, for example: <?php namespace Acme\DemoBundle\EventListener\Doctrine; use Acme\DemoBundle\Entity\Top; use Doctrine\Common\EventSubscriber; use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Events; class TopChangedSubscriber implements EventSubscriber { /** * On flush event * * @param OnFlushEventArgs $event */ public function onFlush(OnFlushEventArgs $event) { $em = $event->getEntityManager(); $uow = $em->getUnitOfWork(); $topMetadata = $em->getClassMetadata('DemoBundle:Top'); foreach ($uow->getScheduledEntityInsertions() as $top) { if ($top instanceof Top) { $top->setChanged(301 - $top->getPosition()); // So, i call to recompute, because entity changed. // BUG #1? This entity added to entity updates, and getScheduledEntityUpdates returned incorrect data // BUG #2? This entity has been insert (1 SQL query) and update (2 SQL query)! $uow->recomputeSingleEntityChangeSet($topMetadata, $top); } } foreach ($uow->getScheduledEntityUpdates() as $top) { if ($top instanceof Top) { $changes = $uow->getEntityChangeSet($top); if (isset($changes['position'])) { list ($oldPosition, $newPosition) = $changes['position']; $top->setChanged($oldPosition - $newPosition); $uow->recomputeSingleEntityChangeSet($topMetadata, $top); } } } } /** * {@inheritDoc} */ public function getSubscribedEvents() { return array(Events::onFlush); } } Thank.
          Hide
          Marco Pivetta added a comment -

          Vitaliy Zhuk as I've already explained in https://github.com/doctrine/doctrine2/commit/d473824279bfee19772bb1692d2a3453a2aff233#commitcomment-5796295, you are not supposed to re-compute changes for insertions.

          Show
          Marco Pivetta added a comment - Vitaliy Zhuk as I've already explained in https://github.com/doctrine/doctrine2/commit/d473824279bfee19772bb1692d2a3453a2aff233#commitcomment-5796295 , you are not supposed to re-compute changes for insertions.
          Hide
          Vitaliy Zhuk added a comment -

          Ok, i can change entity field in insert action?

          Show
          Vitaliy Zhuk added a comment - Ok, i can change entity field in insert action?

            People

            • Assignee:
              Benjamin Eberlei
              Reporter:
              Matthieu Napoli
            • Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: