5

我正在尝试检测事件中多对多关系的变化onFlush

如果将新实体添加到关系或更新关系(始终保留一个元素),我可以使用 检测更改$unitOfWork->getScheduledCollectionUpdates(),然后检查getInsertDiff()or getDeleteDiff()。到现在为止还挺好。

当我从关系中取出所有实体时,问题就出现了:“以前有两个相关实体,但现在没有相关实体。”

当关系为空时,我可以访问$unitOfWork->getScheduledCollectionDeletions(),但无法知道哪些实体被删除:

  • getDeleteDiff()因为这个系列并没有说明什么。
  • getSnapshot()没有告诉我之前有哪些实体

我应该如何知道从多对多关系中取出了哪些实体?


我添加了一个完整实现的要点:一切正常(可能需要一些优化),除了$uow->getScheduledCollectionDeletions()(第 101 行)

https://gist.github.com/eillarra/5127606

4

1 回答 1

9

这个问题的原因有两个:

1) 当clear()在 a 上调​​用该方法时Doctrine\ORM\PersistentCollection,它将:

  1. 清除其内部实体集合。
  2. 呼吁。scheduleCollectionDeletion()_Doctrine\ORM\UnitOfWork
  3. 拍摄自己的新快照。

2 号是您的收藏出现在$uow->getScheduledCollectionDeletions()(而不是$uow->getScheduledCollectionUpdates())中的原因。第 3 点是您无法确定收藏品在被清除之前包含哪些内容的原因。

2) 当使用 Symfony2 Form 组件时,特别是ChoiceTypeorCollectionType类型与 option 的组合,当所有实体都应该从集合中删除时multiple,该clear()方法将被调用。

这是由于在MergeDoctrineCollectionListener此处添加的: https ://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php#L55

这是作为优化完成的:以这种方式清除集合更快,而不是检查应该从中删除哪些实体。

我可以想到两种可能的解决方案

1) 创建一个 forksymfony/symfony并实现一个选项,以便添加MergeDoctrineCollectionListener. 也许像no_clear阻止添加监听器之类的东西。这不会引入 BC 中断并且会解决您的问题,因为当所有实体都应该被删除clear()时,集合的方法不会被调用。

2)重新设计你的计数器:也许还可以监听OnLoad可以在从数据库中获取集合时计算集合中实体数量的事件。这样,您的OnFlush侦听器可以使用该数字来了解在清除集合时从集合中删除了多少实体。

于 2013-03-13T19:05:53.950 回答