0

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

Теперь, когда я пытаюсь добавить другого подписчика событий 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 ] ] 

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

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

Listener "SoftDeleteableListener" was not added to the EventManager! 

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

ответ

2

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

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

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

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

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

+0

Благодарим за сообщение. Награда за вас за 23 часа. – TautrimasPajarskas

+0

О, не загружайте теги в 'postLoad'. Просто укусил это сегодня. Потому что, если вы выполняете DQL-запрос, 'postLoad' будет вызываться, когда объект гидратируется, но до создания какой-либо ассоциации (см. Примечания [здесь] (http://docs.doctrine-project.org/en/latest/reference /events.html#lifecycle-events) .Так что если вы «loadTagging» здесь, гидратор каким-то образом потеряет некоторые требуемые данные, чтобы продолжить заполнять другие ассоциации. И вы будете царапать голову, задаваясь вопросом, почему, как и я. –

Смежные вопросы