我正在开发一个Doctrine应用程序,我在两个实体之间有一对多的关系,我将其称为'Foo'和'Bar'。 '酒吧'是关系的拥有方,在这种情况下这可能看起来很奇怪。我需要一个接一个地处理属于foo的所有酒吧并刷新更改。但是,酒吧实体的体积非常大(每个几兆字节)。由于每个foo都可能有很多条,所以一个微不足道的循环会占用我所有的RAM。我试图通过冲洗和分离解决这个每栏已被处理后满脸通红,像这样:分离作为关系一部分的原则实体
foreach ($foo->getBars() as $bar) {
$bar->setSomething(...potentially large blobs...);
// ... dozens of more setters (and getters)
$em->flush();
// or: $em->flush($bar);
$em->detach($bar);
}
// unrelated code
$foo->setDoStuff(...)
$em->flush();
但是失败严重的第二次迭代,因为某些原因,第二次冲洗()会遇到对象图中的第一个栏,并抱怨它没有被保留(它是非托管的)。错误消息是:“通过关系'Foo#bars'发现了一个新实体,该关系未配置为级联实体的持久化操作”
如果我只刷新特定的$ bar而不是所有实体,则循环成功完成,但后来无法再使用$ em-> flush(),因为它会遇到那些非托管实体。
分离$ foo可以解决这个问题,但不幸的是这是不可接受的,因为代码中有很多其他的$ foo引用可能需要修改并在稍后刷新。
我该如何解决这个问题?与clear()/ detach()相关的文档中的所有示例似乎都很平凡,并且不涉及关系。
理想情况下,有一种方法可以将对象恢复到非水合代理延迟加载状态,就像通过$ em-> getReference()获得的那样。垃圾收集器将释放之前由所有字段使用的内存。
如果具体刷新不持续其他实体,你可以尝试使用级联?无论如何,如果内存是一个大问题,也许加载每个都不是最好的选择,你可以首先加载foo的条形码ID,并在循环中分别加载每个条形图并取消设置。 – mickadoo
@mickadoo问题不在于事物不会被刷新。但是,您的评论的第二部分提示了一个很好的方向,我会进行调查。 – jlh