Symfony2 — пакетная обработка доктрины 2

У меня следующая ситуация:

Мне нужно создать большое количество сущностей (Entity C) на основе пары сущностей

  • Объект А (45)
  • Объект B (700000+)
  • Объект C (45 x 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]);, но это высокое потребление памяти

Мне нужно: это освободить память каждого Entity B, после использования, но при этом каждый сброс или по группам а не по одному, и очистить все Entity C


person rkmax    schedule 16.12.2011    source источник
comment
Нет необходимости отсоединять вашу сущность, так как вы регулярно очищаете своего менеджера сущностей.   -  person Herzult    schedule 19.12.2011
comment
это работает нормально, если выполнить $batchSize=50, но это не очень хорошее число для меня   -  person rkmax    schedule 19.12.2011
comment
Это потому, что вы отсоединяете свою сущность перед очисткой, поэтому менеджер сущностей считает ее новой сущностью...   -  person Herzult    schedule 19.12.2011


Ответы (2)


Вызов clear() в диспетчере сущностей отсоединяет ВСЕ объекты (по умолчанию). Кстати, вы можете передать имя сущности, чтобы отсоединить сущности данного типа:

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

Я думаю, вы пытаетесь отсоединить уже отсоединенный объект, и поэтому он рассматривается как новый.

Попробуйте удалить clear() вызов. Вы также можете попробовать удалить вызов detach() и вызвать clear() для выбранных объектов.

person Jakub Zalas    schedule 19.12.2011
comment
я получаю [Doctrine\ORM\ORMException] EntityManager#clear($entityName) not yet implemented. - person rkmax; 19.12.2011
comment
Кажется, это реализовано в основной ветке Doctrine2: github.com/doctrine/doctrine2 - person AlterPHP; 20.12.2011
comment
я установил 2.1.4 последним включенным в с Symfony 2.0.7 - person rkmax; 20.12.2011

Вы должны полностью указать имя объекта

$em->clear('Acme\MyBundle\Entity\EntityB');
$em->clear('Acme\MyBundle\Entity\EntityC');
person Reza S    schedule 07.07.2014