Doctrine EntityManager在嵌套实体中清除方法


Doctrine EntityManager clear method in nested entities

我想使用条理性批量插入处理,以优化大量实体的插入。问题在于清晰的方法。它说这个方法分离由EntityManager管理的所有实体。如果我有一个父实体,它有很多子实体,每个子实体都有它们的子实体,像这样:

  • riseSession
    • 跟踪

所以我有1个骑行,3个轨道,每个轨道有2000个点。我可以在最后一个循环中使用批处理,它负责节省点数。但是如果我使用clear方法,那么如何为点和轨道设置父结点呢?Clear方法会分离它们,对吧?

很快就会达到内存限制。批量flush()的想法是可以的,但是您需要在每个批次结束时clear() EntityManager以释放已使用的内存。

但在你的情况下,你将有ORMInvalidArgumentException(又名。如果您在调用$entityManager->clear();之后调用$child->setParent($parent);

问题是$parent现在在UnitOfWork中处于detached状态。所以你需要再次把它放在managed状态。这可以通过使用$entityManager->merge();或简单地使用$parentRepository->find($parent->getId());来完成。

只要确保在每个clear()之后将所有实体都设置为managed状态,以防以后使用它们

如果你已经在内存中加载了所有40000个对象,那么你可以只使用代码而不清除。清理实体管理器用于优化PHP脚本中的内存。如果你有足够的内存来存储所有的对象,你根本不需要清除实体管理器。

为了在这种情况下优化内存,您可以在每次持久化后执行unset($entity)

为了适应DB连接带宽,您可以将几个实体分组,如示例所示。

$batchSize = 20;
for ($i = 1; $i <= 10000; ++$i) {
    $em->persist($entities[$i]);
    unset($entities[$i]);
    if (($i % $batchSize) === 0) {
        $em->flush();
    }
}
$em->flush(); //Persist objects that did not make up an entire batch