Symfony 2 event listener for one object runs on each object load

I am new to Symfony and follow the Jobeet tutorial . I have three objects - Job, Category and User. I have the following service listener.

CSI / IVT / JobeetBundle / Resources / configurations / services.yml

services:
    ibw.jobeet.entity.job.container_aware:
        class: Ibw\JobeetBundle\Doctrine\Event\Listener\JobListener
        calls:
            - [setContainer, ["@service_container"]]
        tags:
            - { name: doctrine.event_listener, event: postLoad }

SRC / IVT / JobeetBundle / Doctrine / Event / Listener / JobListener.php

<?php
namespace Ibw\JobeetBundle\Doctrine\Event\Listener;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;

class JobListener
{
    /** @var ContainerInterface */
    protected $container;

    /**
    * @param ContainerInterface @container
    */
    public function setContainer(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * @ORM\PostLoad
     */
    public function postLoad(LifecycleEventArgs $eventArgs)
    {
        $entity = $eventArgs->getEntity();
        if (method_exists($entity, 'setContainer')) {
            $entity->setContainer($this->container);
        }
    }
}

I expected it to postLoadbe called only for the Job object , but I found that it is also called for the other two objects, Category and User . I define only setContainerin the Job object . So, I got the undefined method for other objects. My workaround is to check with method_exists.

postLoad ?

+4
3

- , , , , .

  • Entity Listener , no-arg.
  • Entity Listener .
  • , .

Entity

namespace Your\WhateverBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\EntityListeners({"Your\WhateverBundle\EntityListener\JobListener"})
 * @ORM\Table(name="job")
 */
class Job
{
   // Your properties, getters and setters
}

EntityListener

namespace Your\WhateverBundle\EntityListener;

use Your\WhateverBundle\Entity\Job;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;

class JobListener
{
    /** @ORM\PostLoad */
    public function postLoadHandler(Job $job, LifecycleEventArgs $args)
    {
        // Do whatever you want
    }
}
+3

Doctrine 2.4 , Entity listener, . , . Symfony, . , , . , @EntityListeners ({ " " }) @Entity ( XML YAML, ) Doctrine. , - .

+2

, Listener Entity. .

# src/vendor/yourBundle/Entity/JobListener.php
namespace VENDOR\YourBundle\Entity;

use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use VENDOR\YourBundle\Entity\Job;

/**
 * Class JobListener
 * @package VENDOR\YourBundle\Entity
 */
class JobListener {

    public function postLoad( Job $job, LifecycleEventArgs $args ) {
        .....
    }
}
# src/vendor/yourBundle/Resources/config/doctrine/Job.orm.yml
VENDOR\YourBundle\Entity\Job:
type: entity
...
entityListeners:
    VENDOR\YourBundle\Entity\JobListener: ~
...

# src/vendor/yourBundle/Entity/Job.php
/**
* @ORM\Entity
* @ORM\EntityListeners({"VENDOR\YourBundle\Entity\JobListener"})
*/
class Job {
    .....
}

If you need to add some service to your Listener, you need to add some similar configuration.

# app/config/services.yml
# or
# src/vendor/yourBundle/Resources/config/services.yml
doctrine.job_listener:
    class: Vendor\YourBundle\Entity\JobListener
    arguments: ["Path\To\Your\Service"]
    tags:
        - { name: doctrine.orm.entity_listener }
+1
source

All Articles