Symfony2 - doctrine2批处理

8
我有以下情况:
我需要基于一对实体(Entity A和Entity B)创建大量实体(Entity C)。
- Entity A(45) - Entity B(700000+) - Entity C(45 x 700000) - Entity D
因此,我决定采取以下措施:
$AEntities = $em->getRepository('MyBundle:EntityA')->findAll();
$DEntity = $em->getRepository('MyBundle:EntityD')->findOneBy($params);

$iterableResult = $em->getRepository('MyBundle:EntityB')
                ->createQueryBuilder('b')
                ->getQuery()->iterate();
$batchSize = 50

while (($row = $iterableResult->next()) !== false) {
  foreach($AEntities as $AEntity) {
    $entity = new Entity\EntityC();
    $entity->setEntityD($DEntity);
    $entity->setEntityB($row[0]);
    $entity->setEntityA($AEntity);
    $em->persist($entity);
  }

  if(($i % $batchSize) == 0){
    $em->flush();
    $em->clear();
  }
  $em->detach($row[0]);
  $i++;
}

$em->flush();

我按照doctrine2-batch-processing的指示进行操作。

但是当我执行$em->detach($row[0]);并且flush时,出现了一个错误:“通过关系找到了一个新实体...”

我已经尝试过没有使用$em->detach($row[0]);,但这会导致内存消耗过高。

我需要:释放每个实体B的内存,在使用后释放,但同时可以批量处理而不是逐个处理,并清除所有实体C。


1
你不需要分离你的实体,因为你经常清除你的实体管理器。 - Herzult
这个在执行 $batchSize=50 时可以正常工作,但对我来说不是一个好的数字。 - rkmax
因为在刷新之前您将实体分离,所以实体管理器将其视为新实体... - Herzult
2个回答

1

你必须完全指定实体名称

$em->clear('Acme\MyBundle\Entity\EntityB');
$em->clear('Acme\MyBundle\Entity\EntityC');

1

调用清除()在实体管理器上会分离所有对象(默认情况下)。顺便说一句,您可以传递实体名称以分离给定类型的实体:

$em->clear('EntityB'); 
$em->clear('EntityC');

我认为你正在尝试分离已经分离的实体,因此它被视为新实体。

尝试删除 clear() 调用。您还可以尝试删除 detach() 调用,并在选定的实体上调用 clear()


我收到了 [Doctrine\ORM\ORMException] EntityManager#clear($entityName) not yet implemented. 的错误信息。 - rkmax
它似乎已经在Doctrine2的主分支中实现了:https://github.com/doctrine/doctrine2 - AlterPHP
我已经安装了2.1.4,这是与Symfony 2.0.7一起包含的最后一个版本。 - rkmax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接