Метод очистки Doctrine EntityManager во вложенных объектах

Я бы хотел использовать обработку пакетной вставки доктрины , чтобы оптимизировать вставку большого количества объектов. Проблема заключается в методе Clear. В нем говорится, что этот метод отделяет все объекты, которыми управляет EntityManager. Итак, что мне делать в ситуации, когда у меня есть родительский Entity, у которого много детей, и у каждого ребенка есть свои дети, например:

  • riseSession
    • трек
      • точки

Таким образом, у меня есть 1 rideSession, 3 трека и каждый трек для isntance 2 000 очков. Я могу использовать пакетную обработку в последнем цикле, который отвечает за сохранение точек. Но если я использую чистый метод, то как установить родителей для очков и треков? Открытый метод отделит их, не так ли?

Related of "Метод очистки Doctrine EntityManager во вложенных объектах"

Скоро вы достигнете предела памяти. Идея flush() в партиях в порядке, но вам нужно clear() EntityManager в конце каждой партии, чтобы освободить используемую память.

Но в вашем случае у вас будет ORMInvalidArgumentException (иначе называемый «новый объект foung через отношения»), если вы $child->setParent($parent); после того, как вы сделали $entityManager->clear(); ,

Проблема в том, что $parent теперь находится в detached состоянии в UnitOfWork . Поэтому вам нужно снова ввести его в managed состояние. Это можно сделать, используя $entityManager->merge(); или просто используя $parentRepository->find($parent->getId()); ,

Просто убедитесь, что после каждого clear() в случае, если вы собираетесь использовать их позже, вы должны вернуть все Entities в managed состояние.

Если у вас есть все 40000 объектов, которые уже загружены в память, вы можете просто использовать код без очистки. Очистка диспетчера объектов используется для оптимизации памяти в PHP-скрипте. Если у вас достаточно памяти для хранения всех объектов, которые вам не нужны, чтобы вообще удалить диспетчер объектов.

Для оптимизации памяти в этом случае вы можете unset($entity) после каждого сохранения.

А для того, чтобы соответствовать пропускной способности БД, вы можете группировать несколько объектов, как в примере.

 $batchSize = 20; for ($i = 1; $i <= 10000; ++$i) { $em->persist($entities[$i]); unset($entities[$i]); if (($i % $batchSize) === 0) { $em->flush(); } } $em->flush(); //Persist objects that did not make up an entire batch не $batchSize = 20; for ($i = 1; $i <= 10000; ++$i) { $em->persist($entities[$i]); unset($entities[$i]); if (($i % $batchSize) === 0) { $em->flush(); } } $em->flush(); //Persist objects that did not make up an entire batch