如果一对多关联发生更改,则会调用symfony事件侦听器preUpdate

时间:2017-10-19 09:07:33

标签: php symfony doctrine-orm entity event-listener

我有一个与另一个实体有OneToMany关系的实体。

含义实体

/**
 * One Meaning has Many Tags.
 *
 * @ORM\OneToMany(targetEntity="Tag", mappedBy="meaning")
 */
private $tags;

标记实体

/**
 * Many Tags have One Meaning.
 *
 * @ORM\ManyToOne(targetEntity="Meaning", inversedBy="tags")
 * @ORM\JoinColumn(name="meaning_id", referencedColumnName="id")
 */
private $meaning;

我为preUpdateprePersist学说事件注册了一个事件监听器。

services.yml

tag.event_listener.meaning_tag_persister:
    class: TagBundle\EventListener\MeaningTagsPersister
    tags:
        - { name: doctrine.event_listener, event: preUpdate, method: preUpdate }
        - { name: doctrine.event_listener, event: prePersist, method: prePersist }

在此事件监听器中,我所做的就是在meaning实体中设置tag

MeaningTagsPersister.php

/**
 * Call before an entity gets updated
 *
 * @param PreUpdateEventArgs $args
 */
public function preUpdate(PreUpdateEventArgs $args)
{
    /** @var Entry $object */
    $object = $args->getObject();

    if (!$object instanceof Meaning) {
        return;
    }

    /** @var Tag $tag */
    foreach($object->getTags() as $tag) {
        $tag->setMeaning($object);
    }
}

prePersist方法看起来完全一样。每当我创建一个新的Meaning实体时,都会使用适当的方法调用事件监听器。当我更新Meaning实体时,事件监听器也可以正常工作,但只有当我更新其中一个" normal"像name这样的属性。如果我更改tags中的任何内容,则doctrine无法将其识别为已更改的实体(这是正确的,因为Meaning实体本身尚未更改)。

然而,当meaning实体更新时,我仍需要更新每个Tag内的Meaning。我还必须从不再与meaning相关联的Tag中删除Meaning

事件监听器是否是实现此目的的正确方法?如果是,如果仅Meaning已更改,如何让preUpdate实体触发tags事件?如果不是,通过Tag实体更新所有关联的Meaning实体的适当方法是什么?

2 个答案:

答案 0 :(得分:0)

您正在使用应添加的学说生命周期事件

/** @Entity @HasLifecycleCallbacks */

到您的MeaningTag个实体。

参考:Doctrine Lifecycle Callbacks

答案 1 :(得分:0)

此处的问题是PreUpdate无法处理Associations中的更改,如文档中所述:

  

...在此事件中永远不允许对更新实体的关联进行更改,因为在刷新操作的此时,Doctrine无法保证正确处理引用完整性。

Doctrine#PreUpdate

要验证,请在Controller中执行相同的代码,它将保留更改。