I have read the docs about lifecycle events, and several questions here on SO about changing or persisting new entities during lifecycle events. Calling EnitityManager::flush()
seems to be a problem.
Ok, but looking carefully at the docs, there is a code example where the field is changed in postPersist, but no flush is called.
I checked that, and the suggested change is not written to the DB. Only the object being persisted does receive the change.
<?php
/** @Entity @HasLifecycleCallbacks */
class User
{
// ...
/**
* @Column(type="string", length=255)
*/
public $value;
/** @PostPersist */
public function doStuffOnPostPersist()
{
$this->value = 'changed from postPersist callback!';
}
}
Maybe one should add this to the docs. I was mislead at first.
However, when adding the LifecyleEventArgs argument and flushing the contained EntityManager, they are written to DB:
/** @PostPersist */
public function doStuffOnPostPersist(LifecycleEventArgs $args)
{
$this->value = 'changed from postPersist callback!';
$args->getEntityManager()->flush(); // works in my tests. Is this safe to use ?
}
I don't know how to interpret the docs about whether it is OK or not to call flush
inside the postPersist.
As you can see, I am searching for a reliable way to perform some kind of postprocessing to my entities after inserting or updating them. I have to use postPersist, since I need the auto-generated primary key value.
Side question: If yes, it is ok to flush, could I then also persist other objects in PostUpdate? Like so:
/** @PostPersist */
public function doStuffOnPostPersist(LifecycleEventArgs $args)
{
$this->value = 'changed from postPersist callback!';
$obj = new OtherObject("value " . $this->value);
$args->getEntityManager()->persist($obj);
$args->getEntityManager()->flush(); // works in my tests. Is this safe to use ?
}
Side-side question: I have tried the last variant, and it seems to work. But is it efficient, or am I possibly creating deep recursion stacks? According to the docs, the postPersist code is called during flush, so if I call flush during postPersist, I have to be careful not to persist an object that executes the same handler, which would lead to infinite recursion. Is this correct?