2011-12-16 34 views
8

Iは、以下の状況がある:Symfony2の - doctrine2バッチ処理

Iエンティティ

  • エンティティA(45)
  • のペアに基づいたエンティティ(エンティティC)の多数を作成する必要が
  • エンティティB(700000+)
  • エンティティC(45×700000)
  • エンティティ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]);とフラッシュが新しいエンティティが関係を通じて発見されたエラーを取得します...

私はを必要とせずに$em->detach($row[0]);しようとしましたが、この高いメモリ消費量

いる:メモリ0を解放することですそれぞれのエンティティBは、使用後に同時にフラッシュされるか、グループごとに1つずつ削除され、すべてのエンティティCは消去されます。

+1

を指定する必要があります。 – Herzult

+0

'$ batchSize = 50'を実行するとうまく動作しますが、私にはいい数字ではありません – rkmax

+0

フラッシングの前にエンティティをデタッチしてエンティティマネージャが新しいエンティティと見なすからです... – Herzult

答えて

1

clear() on entity managerをコールすると、すべてのオブジェクトがデタッチされます(デフォルト)。ところで、あなたは、特定のタイプのエンティティをデタッチするエンティティ名を渡すことができます:

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

私はあなたがすでに取り外されたエンティティを切り離すしようとしているので、それが新規として扱わだと思います。

clear()コールを削除してみます。 detach()コールを削除して、選択したエンティティでclear()と電話をかけてみることもできます。

+0

' [Doctrine \ ORM \ ORMException] EntityManager#clear($ entityName)はまだ実装されていません。 ' – rkmax

+0

Doctrine2のマスターブランチに実装されているようです:https://github.com/doctrine/doctrine2 – AlterPHP

+0

'2.1.4'がインストールされています最後に 'Symfony 2.0.7'に含まれています – rkmax

1

あなたは完全にそれはあなたがregularyあなたのエンティティマネージャをクリアすると、あなたのエンティティを取り外す必要はありませんエンティティ名

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