我有一个
Application
实体,它与 SortList
实体具有多对多关系。拥有方是Application
。有一个简单的联接表可以创建此关系的映射。
以下是
Application
实体在管理集合方面的外观:
/**
* Add sortLists
*
* @param \AppBundle\Entity\SortList $sortList
* @return Application
*/
public function addSortList(SortList $sortList)
{
$this->sortLists[] = $sortList;
$sortList->addApplication($this);
return $this;
}
/**
* Remove sortLists
*
* @param \AppBundle\Entity\SortList $sortList
*/
public function removeSortList(SortList $sortList)
{
$this->sortLists->removeElement($sortList);
$sortList->removeApplication($this);
}
/**
* Get sortLists
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getSortLists()
{
return $this->sortLists;
}
我想跟踪何时从
SortLists
添加或删除
Application
。
我已经了解到我无法使用
postUpdate
生命周期事件来跟踪这些更改集合。
相反,我似乎应该使用 onFlush,然后使用
$unitOfWork->getScheduledCollectionUpdates()
和 $unitOfWork->getScheduledCollectionDeletions()
。
对于更新,我发现我可以使用“内部”方法
getInsertDiff
来查看集合中添加了哪些项目,并 getDeleteDiff
来查看集合中哪些项目被删除。
但我有一些担忧:
$unitOfWork->getScheduledCollectionDeletions()
没有此信息。我在https://stackoverflow.com/a/75277337/5418514
中解决了这个空的getDeleteDiff有时这是空的原因是一个古老但仍然存在的问题。目前的解决办法就是自己重新取数据。
public function onFlush(OnFlushEventArgs $args)
{
$uow = $args->getEntityManager()->getUnitOfWork();
foreach ($uow->getScheduledCollectionDeletions() as $collection) {
/**
* "getDeleteDiff" is not reliable, collection->clear on PersistentCollection also clears the original snapshot
* A reliable way to get removed items is: clone collection, fetch original data
*/
$removedData = $collection->getDeleteDiff();
if (!$removedData) {
$clone = clone $collection;
$clone->setOwner($collection->getOwner(), $collection->getMapping());
// This gets the real data from the database into the clone
$uow->loadCollection($clone);
// The actual removed items!
$removedData = $clone->toArray();
}
}
}
我尝试了上述方法,但没有成功,但我发现更简单的方法是将它们一一删除,例如
foreach ($collection->toArray() as $item) {
$collection->removeElement($item);
}
这允许我在从集合中删除项目时记录更改。但来到这里实际上帮助我了解我的问题是什么(使用 $collection->clear() )
我认为下面的示例涵盖了您需要的所有内容,因此您只需在应用程序中实现您想要/需要的内容即可。
persist
操作,您可以使用 prePersist 和
实体上的 postPersist 事件侦听器 或 prePersist 和
实体上的 postPersist 事件订阅者示例。预坚持
不会给你ID,因为它还不存在于数据库中,而
PostPersist 将如示例所示。remove
操作,您可以使用 preRemove 和
实体上的 postRemove 事件侦听器 示例。update
操作,这是一个棘手的操作,您可以使用
实体上的 preUpdate 事件侦听器示例,但请注意
它是如何完成的。inserting
、updating
和 removing
操作,您可以使用
实体上的 onFlush 事件监听器示例,涵盖
工作单元getScheduledEntityInsertions
,
getScheduledEntityUpdates
和 getScheduledEntityDeletions
方法。该网站中还有许多其他有用的侦听器示例,因此只需使用 listener
关键字的搜索功能即可。有一次我对 M-N 关联做了同样的事情,但找不到例子。如果可以的话我会发布它,但不确定是否可以!