Search code examples
symfonydoctrineentitylisteners

Doctrine Entity Listener in Symfony 2.6


According to How to use Doctrine Entity Listener with Symfony 2.4? it should be pretty simple to setup the entity listener feature in Symfony.

Unfortunately, my listener nevers gets called and I don't know why. I've checked the compiler pass of the doctrine bundle and also the DefaultEntityListenerResolver class. My listener is gets passed to the register method and should be available then. The resolve method on the other hand seems to be never called.

Here is my service definition:

insite.entity.listener.page_node:
    class: NutCase\InSiteBundle\Entity\PageNodeListener
    tags:
        - { name: doctrine.orm.entity_listener }

Here is my listener:

namespace NutCase\InSiteBundle\Entity;

use Doctrine\ORM\Event\LifecycleEventArgs;

class PageNodeListener
{
    public function prePersist( PageNode $node, LifecycleEventArgs $event )
    {
        die("okay");
    }
}

And here my yaml for the entity:

NutCase\InSiteBundle\Entity\PageNode:
    type: entity
    table: page_node
    repositoryClass: NutCase\InSiteBundle\Entity\PageNodeRepository

    fields:
        title:
            type: string
            length: 255
            nullable: false

        segment:
            type: string
            length: 255
            nullable: false

        url:
            type: string
            length: 255
            nullable: false

        root:
            type: boolean
            nullable: false

        hidden:
            type: boolean
            nullable: false

I've added an "entityListeners" entry to the YAML, since I thought this one is missing:

entityListeners:
  - PageNodeListener // Also tried the full namespace

Which only leads to the following error whenever I try to load a PageNode entity:

[Symfony\Component\Debug\Exception\ContextErrorException]  
  Warning: Invalid argument supplied for foreach()   

Any suggestions?


Solution

  • I just found the code which parses the YAML and also the entityListeners key: YamlDriver. Since I failed to find any documentation for the YAML configuration of this key, I had to check the code, which leads me to the answer that the correct YAML markup for entity listeners should be:

    Your\Entity\Namespace:
      entityListeners:
        Path\To\Your\Listener: ~
    

    In case that you want to map specific methods to specific events, you should use:

    Your\Entity\Namespace:
      entityListeners:
        Path\To\Your\Listener:
           prePersist: [methodOnYourListener]
    

    Guess the question would be needles if there were any documentation for that.

    I also like to point out that you don't have to register your listeners as a service. The class name in the YAML mapping of the entity is actually enough to get it running, since the DefaultEntityListenerResolver will create an instance if there is none yet. You only need to register the listener as a service if you have other dependencies, like the security context for example.