The documentation says: https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/events.html#postupdate-postremove-postpersist
The three post events are called inside EntityManager#flush(). Changes in here are not relevant to the persistence in the database, but you can use these events to alter non-persistable items, like non-mapped fields, logging or even associated classes that are not directly mapped by Doctrine.
So let's imagine I have an Image entity:
<?php
/**
* @ORM\Entity
*/
class Image
{
/**
* @var int|null
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
* @ORM\Column(type="integer")
*/
private ?int $id = null;
/**
* @var string
* @ORM\Column(type="string")
*/
private string $path;
/**
* @var string
* @ORM\Column(type="string")
*/
private string $status = 'RECEIVED';
}
Once I flush my Image entity I want to upload the corresponding file on a FTP server, so I do it in the postPersist event.
But if the upload on FTP fail I want to change the status of my Image to FTP_ERROR.
<?php
public function postPersist(Image $image, LifecycleEventArgs $event)
{
$em = $event->getEntityManager();
try {
$this->someService->uploadToFtp($image);
} catch (Exception $e) {
$image->setStatus('FTP_ERROR');
$em->persist($image);
$em->flush();
}
}
And it works, but as documentation says it's not a good way to do it.
I have seen this post: Flushing in postPersist possible or not? which says:
@iiirxs:
It is ok to call flush() on a PostPersist lifecycle callback in order to change a mapped property of your entity.
So how to do so? @iiirxs and the documentation say 2 different things.
postPersistis only triggered after the entity is saved first (sql insert), flushing after that will only trigger an sql update (maybe replace idk), so you won't get infinite loops; so firstly you should remove the persist() call from thepostPersiteventhandler. you might not get loops, because theentityManagerfinds the entity and only updates it, but surely you are making it do extra things. Once the entity is persisted, no morepostPersistevents should trigger on that entity, onlypostUpdates. So your solution should be fine - zedling