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?
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
TagListener
, then load fpn_tag.tag_manager
on demand.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.