Исключение Symfony при регистрации нового подписчика событий Doctrine (SoftDeleteable)

Я использую Symfony 2.3 с Sonata Admin Bundle с DoctrineExtensions (который включен StofDoctrineExtensionsBundle). Я включил, настроил и успешно протестировал компоненты SoftDeleteable и Timestampable.

Теперь, когда я пытаюсь добавить еще одного подписчика событий Doctrine с помощью службы тегов Symfony, кажется, что прослушиватель softdeleteable отключен.

Мой сервис:

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

Подписчик:

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',
        );
    }
}

В каждом запросе я получаю исключение:

Listener "SoftDeleteableListener" was not added to the EventManager!

Если я отключу своего подписчика, проблема исчезнет. Как включить моего подписчика на события, а также иметь softdeleteable?


person TautrimasPajarskas    schedule 05.07.2013    source источник


Ответы (1)


У меня такая же проблема, как и у вас сегодня.

Проблема в том, что fpn_tag.tag_manager зависит от doctrine.orm.default_entity_manager, но TagListener является зависимостью от doctrine.orm.default_entity_manager, если вы пометите его тегом doctrine.event_subscriber. Таким образом, создается циклическая зависимость. Но это не обнаруживается контейнером службы, вместо этого он пытается добавить события после возврата службы подключения доктрины. Подробнее см. здесь.

Есть два способа это исправить

  1. Вы можете внедрить сервисный контейнер в TagListener, а затем загрузить fpn_tag.tag_manager по требованию.
  2. Создайте прослушиватель для события kernel.request, затем вручную добавьте подписчика на событие в менеджер сущностей.

Кстати, я бы рекомендовал не вызывать saveTagging внутри событий preUpdate и prePersist. Потому что saveTagging выполняет неявный сброс, который небезопасно вызывать в этих событиях.

person Patrick Li    schedule 05.08.2013
comment
Спасибо за обмен этой информацией. Вознаграждение за вас в течение 23 часов. - person TautrimasPajarskas; 06.08.2013
comment
О, и теги в postLoad тоже не загружайте. Вот только сегодня укусил. Потому что, если вы выполняете запрос DQL, postLoad будет вызываться при гидратации объекта, но до создания какой-либо связи (см. примечания здесь. Так что, если вы loadTagging здесь, гидратор каким-то образом потеряет некоторые необходимые данные, чтобы продолжить заполнение других ассоциаций. И вы будете ломать голову, задаваясь вопросом, почему как я сделал. - person Patrick Li; 07.08.2013