Неопределенная ошибка индекса при $ em-> gt; clear () в Symfony3 / Doctrine2

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

[Symfony \ Component \ Debug \ Exception \ ContextErrorException] Примечание: неопределенный индекс: 000000000fa82729000000006e17190b

Я перепробовал все советы от эта почта.

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

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

2

Решение

Одна из основных проблем:

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

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

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

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

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

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

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

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

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

1

Другие решения

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

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

Когда я проверял примеры веб-сайтов Doctrine о пакетная обработка, Я был больше обеспокоен частью 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 за то, что указал мне в этом направлении.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector