2017-01-20 4 views
2

Я получаю эту ошибку:

[Symfony\Component\Debug\Exception\ContextErrorException] Notice: Undefined index: 000000000fa82729000000006e17190b

Я попробовал все советы от this post.

Мой код намного проще, чем коды других плакатов (вопрос об этой проблеме).

$em = $this->getContainer()->get('doctrine')->getManager(); 
    $pictureUrlRepository = new ProductItemPictureUrlRepository($em); 
    $pictures = $pictureUrlRepository->findAll(); 

    for ($i = 0; $i < 4; ++$i) { 
     $productItem = $pictures[$i]->getProductItem(); 
     dump($productItem->getId()); 
     $fileName = 'file_' . $i; 

     $productItemPicture = new ProductItemPicture(); 
     $productItemPicture->setProductItem($productItem); 
     $productItemPicture->setFile($fileName); 
     $productItemPicture->setPosition(1); 
     $productItemPicture->setSize(1000); 
     $productItemPicture->setWidth(1200); 
     $productItemPicture->setHeight(1000); 

     $em->persist($productItemPicture); 
     $em->flush(); 
     $em->clear(); 
     unset($productItemPicture); 
    } 

Чтобы показать вам, что я пробовал советы от приведенной выше ссылки, вот более сложный код с реализованными советами (но результат все тот же):

 $em = $this->getContainer()->get('doctrine')->getManager(); 
    $pictureUrlRepository = new ProductItemPictureUrlRepository($em); 
    $pictures = $pictureUrlRepository->findAll(); 

    foreach ($em->getEventManager()->getListeners() as $event => $listeners) { 
     foreach ($listeners as $listener) { 
      $em->getEventManager()->removeEventListener($event, $listener); 
     } 
    } 

    $batchSize = 2; 
    for ($i = 0; $i < 4; ++$i) { 
     $productItem = $pictures[$i]->getProductItem(); 
     dump($productItem->getId()); 
     $fileName = 'file_' . $i; 

     $productItemPicture = new ProductItemPicture(); 
     $productItemPicture->setProductItem($productItem); 
     $productItemPicture->setFile($fileName); 
     $productItemPicture->setPosition(1); 
     $productItemPicture->setSize(1000); 
     $productItemPicture->setWidth(1200); 
     $productItemPicture->setHeight(1000); 
     $productItemPicture->setCreated(new \DateTime('20.1.2017')); 
     $productItemPicture->setUpdated(new \DateTime('20.1.2017')); 

     $em->persist($productItemPicture); 
     if (($i % $batchSize) === 0) { 
      $em->flush(); 
      $em->clear(); 
     } 
    } 
    $em->flush(); 
    $em->clear(); 

Только когда это Я комментирую (отключает) $ em-> clear(); line, работает. В чем дело с тем, что не работает clear()? Что я могу ожидать при выполнении тысяч записей в БД и не работает clear()?

+0

Не могли бы вы отметить «линию», из которой исходит эта ошибка? Может быть, из кода, который вы выполняете сразу после цикла? –

+0

Когда я комментирую $ em-> clear(); оно работает. Итак, это линия. – Neon

+0

Сколько у вас фотографий? 5? Меньше? – Veve

ответ

1

Одной из основных проблем являются:

// Replace 
$pictureUrlRepository = new ProductItemPictureUrlRepository($em); 

// With 
$pictureUrlRepository = $em->getRepository('AppBundle:ProductItemPictureUrl'); 

Существует сложная связь между диспетчером объектов и его хранилища. Никогда не пытайтесь создать экземпляр репозитория напрямую. Много вещей происходит за кулисами. Удивлен, что ваш findAll даже работал.

Конечно, похоже, что вы добавили слушателей событий доктрины? Поэтому трудно точно сказать, где может быть проблема. Если исправление репозитория не работает, отправьте полную трассировку стека.

Вы также, кажется, полагаетесь на наличие по меньшей мере четырех изображений на продукт, что немного опасно.

============================

Не совсем ясно из ваших комментариев, если проблема была решена с репозиторием предложение. Но использование $ em-> clear в то же время, когда вы полагаетесь на $ pictures, тоже немного опасно. Не сообщая, что происходит с объектами, когда вы очищаете менеджера. Поэтому переместите их за пределы петли:

for ($i = 0; $i < 4; ++$i) { 
    $em->persist($productItemPicture); 
} 
$em->flush(); 
$em->clear(); 

И да, я понимаю, что вы, вероятно, достигли пределов памяти, когда ваш процесс много элементов. ORM не очень хорош при больших пакетных заданиях. Возможно, вам придется отказаться от использования объекта соединения DBAL.

+0

Спасибо за интерес. Я понимаю вашу озабоченность по поводу «новой» части с репозиториями. Я новичок в Symfony, и я добавил эту «новую» часть только из-за размещения кода здесь в Stackoverflow. И причина в том, что я нашел аналогичный код в другой части проекта, закодированный другим программистом, и этот код работает. Итак, я сам использовал этот код $ doctrine-> getRepository (ProductItemPictureUrl :: class), который, как я надеюсь, совпадает с опубликованным вами. – Neon

+0

Я не использую прослушиватели событий. В моем втором примере кода я отменяю их регистрацию только потому, что предыдущие ответы в другом потоке предположили это, в случае присутствия какого-либо внутреннего слушателя. – Neon

+0

В моем производственном коде также неверно полагаться на количество изображений. Эта действительная функция предназначена только для тестирования, чтобы отслеживать эту ошибку. – Neon

1

Я нашел, в чем была проблема в моем случае.

Прежде, чем я начну цикл itearation, я получаю все результаты с помощью метода FindAll(). Затем я устанавливаю $ productItem, ссылаясь на результаты массива этого метода. Но clear() в итерационном цикле уничтожает идентификаторы Entity в этом массиве.

Когда я проверял примеры веб-сайта Doctrine около batch processing, я больше беспокоился о части clear(). Но реальная проблема заключается в том, как они получают результаты, которые они выполняют. Они используют методы iterate() для результата createQuery().

Итак, обновленный код, работающий результат заключается в следующем:

$em = $this->getContainer()->get('doctrine')->getManager(); 
    $q = $em->createQuery('select p from AppBundle\Model\Product\Item\ProductItemPictureUrl p'); 
    $iterableResult = $q->iterate(); 

    $i = 0; 
    foreach ($iterableResult as $row) { 
     $productItem = $row[0]->getProductItem(); 
     dump($productItem->getId()); 
     $fileName = 'file_' . $i; 

     $productItemPicture = new ProductItemPicture(); 
     $productItemPicture->setProductItem($productItem); 
     $productItemPicture->setFile($fileName); 
     $productItemPicture->setPosition(1); 
     $productItemPicture->setSize(1000); 
     $productItemPicture->setWidth(1200); 
     $productItemPicture->setHeight(1000); 

     $em->persist($productItemPicture); 
     $em->flush(); 
     $em->clear(); 
     unset($productItemPicture); 
     $i++; 
    } 

Благодаря @Cerad за указание мне в этом направлении.

+0

Для справки я нашел эту тему, которая не совсем такая же проблема, но привносит некоторый свет в эту проблему: http://stackoverflow.com/questions/7431794/doctrine-2-weird-behavior-while-batch -переработка-вкладыши-оф-объекты, которые-см – Neon