I am stuck for about a day now on the following
I created a listener on my account entity, It listens to prePersist
, preUpdate
, postPersist
and postUpdate
. I thought postUpdate
was executed after the data has been store in the database, but now i doubt it.
The listener
/**
* 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
}
}
}
The listener should check if one of the important fields has been changed, if so it should send an API request (after the account is updated). However when I update my account it looks like the action inside my API still gets the old account.
Then I tried to die(var_dump($account));
inside the callApi
function. And the result was that the var $account
gave me the updated
entity just like I expected. BUT inside the function callApi()
the data has not been stored into the database yet! (I know this because the values from die(var_dump($account));
are not equal with the values in the database). So in that case its normal that my API still gets the old account from the database.
I don't know why this happens, but to me it looks like the data gets stored after the postUpdate
function has been completely executed.
I would like to know why this happens and if this is normal behavior. I also would like to know how I can make sure the API is called after the data has been stored into the database.
The postUpdate
event is not called after the flush()
but inside the flush. This is why a postFlush
event exists (even if it's not a lifecycle callback).
Check for more information the official Doctrine 2 documentation chapter 9. Events.