Symfony exception when registering new Doctrine event subscriber (SoftDeleteable)

隐身守侯 提交于 2019-12-13 07:40:51

问题


I'm using Symfony 2.3 with Sonata Admin Bundle with DoctrineExtensions (which is enabled by StofDoctrineExtensionsBundle). I enabled, configured and successfully tested SoftDeleteable and Timestampable components.

Now, when I try adding another Doctrine event subscriber using Symfony tagged service, it seems as the softdeleteable listener is being disabled.

My service:

my.contact.listener.tag:
    class: My\ContactBundle\EventListener\TagListener
    tags:
        - { name: doctrine.event_subscriber, connection: default }
    calls:
        - [ setTagManager, [ @fpn_tag.tag_manager ] ]

Subscriber:

namespace My\ContactBundle\EventListener;


use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use DoctrineExtensions\Taggable\Taggable;
use FPN\TagBundle\Entity\TagManager;

class TagListener implements EventSubscriber
{
    /**
     * @var TagManager
     */
    private $tagManager;

    /**
     * @param \FPN\TagBundle\Entity\TagManager $tagManager
     */
    public function setTagManager($tagManager)
    {
        $this->tagManager = $tagManager;
    }

    /**
     * Load tags for Taggable entities
     *
     * @param LifecycleEventArgs $args
     */
    public function postLoad(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Taggable) {
            $this->tagManager->loadTagging($entity);
        }
    }

    /**
     * Save tags for Taggable entities
     *
     * @param LifecycleEventArgs $args
     */
    public function preUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Taggable) {
            $this->tagManager->saveTagging($entity);
        }
    }

    /**
     * Save tags for Taggable entities
     *
     * @param LifecycleEventArgs $args
     */
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Taggable) {
            $this->tagManager->saveTagging($entity);
        }
    }

    public function getSubscribedEvents()
    {
        return array(
            'prePersist',
            'preUpdate',
            'postLoad',
        );
    }
}

In each request I get exception:

Listener "SoftDeleteableListener" was not added to the EventManager!

If I disable my subscriber, the problem is gone. How to enable my event subscriber and have softdeleteable too?


回答1:


I got the same problem as you do today.

The problem is that fpn_tag.tag_manager depends on doctrine.orm.default_entity_manager, but the TagListener is a dependency of doctrine.orm.default_entity_manager if you tag it with doctrine.event_subscriber. Thus creating a circular dependency. But this is not detected by the service container, instead it tries to add the events after the doctrine connection service is returned. See more details here.

There are two ways to fix this

  1. You can inject the service container into the TagListener, then load fpn_tag.tag_manager on demand.
  2. Create a listener on kernel.request event, then manually add the event subscriber to the entity manager.

A side note, I'd recommend against calling saveTagging inside preUpdate and prePersist events. Because saveTagging does a implicit flush, which is not safe to call in these events.



来源:https://stackoverflow.com/questions/17493779/symfony-exception-when-registering-new-doctrine-event-subscriber-softdeleteable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!