Cancel additional Doctrine events for an instance of a given object

To handle some recent critical errors in my application, I set up a Doctrine listener for two events: prePersist

and preRemove

. When an error occurs ...

  • ... while the object is saved, it is deleted.
  • ... while the object is removed, it is retained.

These actions are done with ...

$args->getEntityManager()->remove($args->getEntity());
$args->getEntityManager()->persist($args->getEntity());

      

... respectively. However, if an error is detected as prePersist

well as preRemove

, it creates a cycle of events:

  • The object is saved: prePersist

    starts.
  • An prePersist

    error occurs that causes remove()

    .
  • Object deleted: preRemove

    starting.
  • An preRemove

    error occurs that causes persist()

    .
  • Back to 1.

To avoid this, I would like to cancel any further event handling on my object. In this case: when prePersist

run for the first time, it must somehow mark the object so that it becomes independent of the event chain. If possible, I would like not to add the field to my entity.

Is there any way to implement such a thing? Or maybe I should find another way to undo persistence or deletion in the first place?

+3


source to share


1 answer


You can modify your code to use an event listener instead of an event listener, and then you can easily track any objects that have errors.

Here's some pseudocode to get the idea:



class EventSubscriber implements EventSubscriber
{
    private $hasErrors = [];

    public function getSubscribedEvents()
    {
        return array(
            Events::prePersist,
            Events::preRemove,
        );
    }

    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = ...

        if ($error) {
            if (isset($this->hasErrors[$entity->getId()])) {
                return; // don't remove entity
            }

            $this->hasErrors[$entity->getId()] = true;

            $this->getEntityManager()->remove($entity);
        }
    }

    public function preRemove(LifecycleEventArgs $args)
    {
        $entity = ...

        if ($error) {
            if (isset($this->hasErrors[$entity->getId()])) {
                return; // don't persist entity
            }

            $this->hasErrors[$entity->getId()] = true;

            $this->getEntityManager()->persist($entity);
        }
    }
}

      

0


source







All Articles