嵌套实体中的Doctrine EntityManager clear方法

时间:2015-05-18 13:19:46

标签: php symfony doctrine-orm batch-processing

我想使用doctrine batch insert processing来优化大量实体的插入。问题在于Clear方法。它表示此方法分离由EntityManager管理的所有实体。那么,如果我有一个父实体,有很多孩子,每个孩子都有自己的孩子,我应该怎么办呢?

  • riseSession
    • 轨道

所以我有1个rideSession,3个曲目,每个曲目有2 000个点。我可以在最后一个循环中使用批处理,负责保存点。但是,如果我使用clear方法,那么如何设置父母的积分和曲目?明确的方法会将它们分开,对吧?

2 个答案:

答案 0 :(得分:4)

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

但是在你的情况下,如果你在ORMInvalidArgumentException之后打电话$child->setParent($parent);,你将会$entityManager->clear();(a.k.a。“新的实体通过关系”)。

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

请确保在每个managed之后将所有实体调到clear()状态,以防您以后再使用它们。

答案 1 :(得分:1)

如果您已将所有40000对象加载到内存中,则可以使用代码而不清除。清除实体管理器用于优化PHP脚本中的内存。如果您有足够的内存来存储所有对象,则根本不需要清除实体管理器。

为了在这种情况下优化记忆,你可以在每次坚持后unset($entity)

为了适应数据库连接带宽,您可以将几个实体分组,例如。

$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