我有一个实体X
,其中包含Y
个实体的集合。 Y
实体由实体X
“私有”,这意味着当从集合中删除Y
实体时,应将其从数据库中完全删除。
通常,这可以使用orphanRemoval
来实现,但由于标准的刷新顺序(在集合删除之前集合更新之前的集合插入),Y
实体上的唯一约束注定会失败,如果新的或更新的项目与已删除的项目具有相同的值。
要解决此问题,我通过将已删除的Y
实体存储在单独的数组中(不使用orphanRemoval
)来手动跟踪已删除的public function removeY(Y $y) : X
{
$y->setX(null);
$this->removedYItems[] = $y;
$this->yCollection->removeElement($y);
return $this;
}
实体:
flush
当调用preFlush
操作时,我在/**
* @ORM\PreFlush
*/
public function onPreFlush(PreFlushEventArgs $eventArgs) : void
{
if (count($this->removedYItems) === 0)
{
return;
}
$entityManager = $eventArgs->getEntityManager();
foreach ($this->removedYItems as $removedYItem)
{
$entityManager->remove($removedYItem);
}
$entityManager->flush();
}
事件中手动提交已删除的项目:
flush
最后,我明确调用[Sat Nov 25 00:32:14.016294 2017] [php7:error] [pid 22212] [client 192.168.0.1:59174] PHP Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 262144 bytes) in Unknown on line 0
以确保在任何更新或插入之前从数据库中删除项目。
然而,在调用刷新操作后,网页似乎挂起,当我查看我的服务器日志时,PHP似乎已经耗尽了内存(1GiB):
flush
这是一个(已知的)Doctrine错误导致内存泄漏吗?或者我不应该在preFlush
事件中致电C:Data\
(文档另有说法:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#preflush)?
我使用Doctrine 2.5.9在FreeBSD 11.0 STABLE上运行PHP 7.1.11。我会尽快在另一台机器上测试它。
答案 0 :(得分:0)
如果您正在使用启动器,请将其关闭以进入Doctrine。 了解如何操作here。 已知Sf Profiler在处理大量实体时非常贪婪。
答案 1 :(得分:0)
在做了一些测试之后,canvas.imageSmoothingEnabled = false
事件似乎停留在无限递归循环中(如@ geolim4暗示)。我在GitHub上的Doctrine存储库中创建了一个问题,要求澄清,他们告诉我这是文档中的错误:https://github.com/doctrine/doctrine2/issues/6857。