Почему не получается сохранить новую сущность после preUpdate event?

Эвент
public function preUpdate(LifecycleEventArgs $args)
{
    $entity = $args->getEntity();

    if ($entity instanceof Order) {
        if ($args->hasChangedField('status') && $args->getNewValue('status') == 'stock') {
            $this->container->get('activity_logger')->writeLog($entity, 'purchase');
        }
}

writeLog
public function writeLog ($object, $comment)
{
        $entity = new Stock();
        $entity->setCategory($object->getIsotope()->getCategory()->getId());
        $entity->setComment($comment);
        $entity->setDate(new \DateTime('now'));
        $entity->setUser($object->getUser()->getId());
        $entity->setChange(TRUE);

        $this->em->persist($entity);
        $this->em->flush();
}

Ошибка
FatalErrorException: Error: Maximum execution time of 60 seconds exceeded in vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 523
  • Вопрос задан
  • 4080 просмотров
Решения вопроса 1
@maxloyko Автор вопроса
нашел не совсем красивое решение
$sql = "INSERT INTO table (field1, field2) VALUES ('foo', 'var')";
$stmt = $em->getConnection()->prepare($sql);
$stmt->bindValue('invoice', $invoiceId);
$result = $stmt->execute();
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@sand_alkr
инженер-программист
Я все сущности для проталкивания на этапе preUpdate сохраняю в массив в свойство класса, а на postFlush вытаскиваю и проталкиваю.
class PurchaseListener {

    protected $notifications = array();

    public function preUpdate(LifecycleEventArgs $args) {
        $entity = $args->getEntity();
        $em = $args->getEntityManager();
        if ($entity instanceof Purchase) {
            ...
                    $notification = new Notification();
                    $notification->setUser($entity->getUser())
                        ->setText('блабла')
                        ->setType('success');
                    $this->notifications[] = $notification;
                ...
        }
    }

    public function postFlush(PostFlushEventArgs $event)
    {
        if(count($this->notifications)>0) {
            $em = $event->getEntityManager();
            foreach ($this->notifications as $thing) {
                $em->persist($thing);
            }
            $this->notifications = array();
            $em->flush();
        }
    }
}
Ответ написан
Комментировать
tyz910
@tyz910
Дело в том, что preUpdate вызывается внутри flush. А внутри preUpdate через логгер снова вызывается flush. Нужно или выполнить "сырой" sql без ORM, или вручную вызвать расчет changeset'а вместо flush:

$this->em->persist($entity);
$meta = $this->em->getClassMetadata(get_class($entity));
$this->em->getUnitOfWork()->computeChangeSet($meta, $entity);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы