我有一个与另一个实体有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;
我为preUpdate
和prePersist
学说事件注册了一个事件监听器。
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
实体的适当方法是什么?
答案 0 :(得分:0)
您正在使用应添加的学说生命周期事件
/** @Entity @HasLifecycleCallbacks */
到您的Meaning
和Tag
个实体。
答案 1 :(得分:0)
此处的问题是PreUpdate
无法处理Associations
中的更改,如文档中所述:
...在此事件中永远不允许对更新实体的关联进行更改,因为在刷新操作的此时,Doctrine无法保证正确处理引用完整性。
要验证,请在Controller中执行相同的代码,它将保留更改。