title: how to synchronize a value between two entities
body: <p>My project is a php project built with symfony 2.7 </p>
  
  <p>I have two entities: Lead and Customer.
  Some user action create a Lead entity, and an admin can create a Customer entity based on a Lead.
  Both the Lead and the Customer entity have a one to many relation to an entity Status (a Lead/Customer can have a status)</p>
  
  <p>Up until now the Status of a Lead was independent from that of the Customer created from it (and vice versa), but now, I need to keep them synchronized.
  They have to be the same.</p>
  
  <p>I don't want to do that in controllers, because the status can be changed in many ways, and it's likely new ways will be added.
  So I tried to do it with doctrine PreUpdate event listeners, but for some reason that's just not working (changing the other entity in the first one's PreUpdate event triggers a PreUpdate on the second one - and that probably kills it. but I'm not sure).</p>
  
  <p>I'm going to keep trying fixing the PreUpdate event listeners, unless someone here has a better idea?</p>
  
  <p>Thanks :-)</p>
  
  <h3> Customer PreUpdate listener</h3>
  
  <pre><code>use CRM\CoreBundle\Entity\Customer;
  use Doctrine\ORM\Event\PreUpdateEventArgs;
  
  class CustomerPreUpdateListener
  {
      public function preUpdate(PreUpdateEventArgs $args)
      {
          $entity = $args-&gt;getObject();
          if (!($entity instanceof Customer)) {
              return;
          }
  
          if($this-&gt;isStatusChanged($args)) {
              $this-&gt;syncParentLeadStatus($args);
          }
      }
  
      private function isStatusChanged(PreUpdateEventArgs $args)
      {
          return $args-&gt;hasChangedField('status');
      }
  
      private function syncParentLeadStatus(PreUpdateEventArgs $args)
      {
          /** @var Customer $entity */
          $entity = $args-&gt;getObject();
          if(!$entity-&gt;getLead()) {
              return;
          }
  
          $newStatus = $args-&gt;getNewValue('status');
          $entity-&gt;getLead()-&gt;setStatus($newStatus);
          $args-&gt;getEntityManager()-&gt;persist($entity-&gt;getLead());
      }
  }
  </code></pre>
  
  <h3> Lead PreUpdate listener</h3>
  
  <pre><code>use CRM\BasicLeadsBundle\Entity\Lead;
  use CRM\CoreBundle\Entity\Customer;
  use Doctrine\ORM\Event\PreUpdateEventArgs;
  
  class LeadPreUpdateListener
  {
      public function preUpdate(PreUpdateEventArgs $args)
      {
          $entity = $args-&gt;getObject();
          if (!($entity instanceof Lead)) {
              return;
          }
  
          if($this-&gt;isStatusChanged($args)) {
              $this-&gt;syncCustomerStatus($args);
          }
      }
  
      private function isStatusChanged(PreUpdateEventArgs $args)
      {
          return $args-&gt;hasChangedField('status');
      }
  
      private function syncCustomerStatus(PreUpdateEventArgs $args)
      {
          /** @var Lead $entity */
          $entity = $args-&gt;getObject();
          if(0 === $entity-&gt;getCustomersCreated()-&gt;count()) {
              return;
          }
  
          $newStatus = $args-&gt;getNewValue('status');
          foreach ($entity-&gt;getCustomersCreated() as $customer) {
              /** @var Customer $customer */
              $customer-&gt;setStatus($newStatus);
              $args-&gt;getEntityManager()-&gt;persist($customer);
          }
      }
  }
  </code></pre>