2015-09-03 6 views
1

я застрял в течение приблизительно дня теперь на следующейSymfony 2 postUpdate выполняется до данных хранится

Я создал слушателя на мой счет лица, Он слушает prePersist, preUpdate, postPersist и postUpdate. Я думал, что postUpdate был выполнен после того, как данные были сохранены в базе данных, но теперь я сомневаюсь в этом.

Слушатель

/** 
* Account listener 
*/ 
class AccountListener 
{ 

    private $container; 

    /** 
    * Constructor 
    * 
    * @param ContainerInterface $container 
    */ 
    public function __construct(ContainerInterface $container) 
    { 
     $this->container = $container; 
    } 

    /** 
    * Pre persist 
    * 
    * @param LifecycleEventArgs $args 
    */ 
    public function prePersist(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if ($entity instanceof Accounts) { 
      $this->checkIfApiCallIsNeeded($entity, $args); 
     } 
    } 

    /** 
    * pre update 
    * 
    * @param LifecycleEventArgs $args 
    */ 
    public function preUpdate(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if ($entity instanceof Accounts) { 
      $this->checkIfApiCallIsNeeded($entity, $args); 
     } 
    } 

    /** 
    * Post persist 
    * 
    * @param LifecycleEventArgs $args 
    */ 
    public function postPersist(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if ($entity instanceof Accounts) { 
      $this->callApi($entity, $args); 
     } 
    } 

    /** 
    * Post update 
    * 
    * @param LifecycleEventArgs $args 
    */ 
    public function postUpdate(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if ($entity instanceof Accounts) { 
      $this->callApi($entity, $args); 
     } 
    } 

    /** 
    * Checks if a update should be send to the api and store the result in db 
    * 
    * @param Accounts   $account 
    * @param LifecycleEventArgs $args 
    */ 
    private function checkIfApiCallIsNeeded(Accounts $account, LifecycleEventArgs $args) 
    { 

     $importantProperties = array(
      'contactName', 
      'address', 
      'zipPostal', 
      'city', 
      'stateProvince', 
      'country' 
     ); 

     $callApi = 0; 

     $uow = $args->getEntityManager()->getUnitOfWork(); 
     $changeset = $uow->getEntityChangeSet($account); 

    /** 
    * Check if one of the important properties has been changed 
    */ 
     foreach ($importantProperties as $property) { 
      if (array_key_exists($property, $changeset)) { 
       $callApi = 1; 
      } 
     } 

     /** 
     * Store in database 
     */ 
     $account->setNeedUpdate($callApi); 
    } 

    /** 
    * Update account to api 
    * 
    * @param Accounts $account 
    */ 
    private function callApi(Accounts $account, LifecycleEventArgs $args) 
    { 
     $callApi = $account->getNeedUpdate(); 
     $accountId = $account->getId(); 

     if ($callApi === 1) { 
      // Call the API 
     } 
    } 
} 

Слушатель должен проверить, если один из важных полей было изменено, если так необходимо отправить запрос API (после того, как учетная запись обновляется). Однако, когда я обновляю свою учетную запись, похоже, что действие внутри моего API по-прежнему получает старую учетную запись.

Затем я попытался установить die(var_dump($account)); внутри функции callApi. И результат был в том, что var $account дал мне обновленный объект , как и ожидалось. BUT внутри функции callApi() данные еще не хранятся в базе данных! (Я знаю это, потому что значения от die(var_dump($account)); не равны значениям в базе данных). Таким образом, в этом случае нормальный, что мой API по-прежнему получает старую учетную запись из базы данных.

Я не знаю, почему это происходит, но для меня это похоже на то, что данные сохраняются после того, как функция postUpdate была полностью выполнена.

Я хотел бы знать, почему это происходит, и если это нормальное поведение. Я также хотел бы знать, как я могу убедиться, что API вызывается после того, как данные были сохранены в базе данных.

+2

Событие postUpdate не вызывается после флеша(), но внутри флеша. Вот почему событие postFlush существует (даже если это не обратный вызов жизненного цикла). –

+0

@ Michaël Garrez ответить на ваш комментарий. – malcolm

ответ

2

Событие postUpdate не вызывается после flush(), но внутри флеша. Вот почему существует событие postFlush (даже если это не обратный вызов жизненного цикла).

Для получения дополнительной информации официальный представитель Doctrine 2 documentation chapter 9. Events.

+0

Спасибо! Это решило мою проблему. Я действительно думал, что postUpdate был выполнен после флеша>. < – Szenis

Смежные вопросы