首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >symfony2最大功能嵌套级别达到'100‘,中止!与教条事件听者

symfony2最大功能嵌套级别达到'100‘,中止!与教条事件听者
EN

Stack Overflow用户
提问于 2013-06-07 09:02:08
回答 2查看 3.7K关注 0票数 2

我有事件侦听器preUpdate

代码语言:javascript
运行
复制
public function preUpdate(PreUpdateEventArgs $args) {        
    $user = $args->getEntity();
    if($user instanceof \iTracker\UserBundle\Entity\User) {
        if($args->hasChangedField('userGroup')) {

            $old = $args->getOldValue('userGroup');
            $new = $args->getNewValue('userGroup');

            $em = $args->getEntityManager();

            $old->setAmount($old->getAmount() - 1);
            $em->persist($old);

            $new->setAmount($new->getAmount() + 1);
            $em->persist($new);
            $em->flush();
        }
    }
}

在提交表单后,我得到了FatalErrorException: Error: Maximum function nesting level of '100' reached, aborting! in /var/www/issue/app/cache/dev/classes.php line 6123

在/var/www/issue/app/cache/dev/classes.php中,ErrorHandler处的第6123行->NormalizerFormatter处的/var/www/issue/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php行0->NormalizerFormatter> /var格式中的/var/www/议题/app/cache/dev/classes.php第6198行->/var中的正常化()/www/app/cache/dev/classes.php行6172 at LineFormatter>format()格式/var/www/issue/app/cache/dev/classes.php第6320行抽象AbstractProcessingHandler>handle()在/var/www/议题/app/cache/dev/classes.php第6646行,在Logger->addRecord()中/var/www/app/app/cache/dev/classes.php第6710行在Logger-> /var/www/issue/vendor/symfony/symfony/src/Symfony中调试()/Bridge/Doctrine/Logger/DbalLogger.php第72行DbalLogger-> /var/www/issue/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php第50行在DbalLogger->startQuery()在/var/www/issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php第50行在LoggerChain->startQuery()在/var/www/issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php第774行连接/var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php行447 at BasicEntityPersister>_updateTable()中的/var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php行357 at BasicEntityPersister>update()中的/var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php行984 at UnitOfWork->executeUpdates()中的/var/www/issue/->executeUpdate//var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php /ORM/lib/Doctrine/ORM/UnitOfWork.php第317行at UnitOfWork->commit()在/var/www/issue/src/iTracker/UserBundle/Listener/UserGroupAmount.php第41行中的第355行->/var/www/issue/src/iTracker/UserBundle/Listener/UserGroupAmount.php()

  • 在/var/www/issue/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php第61行中的UserGroupAmount装入->preUpdate()
  • 在/var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php第980行的ContainerAwareEventManager->dispatchEvent()
  • 在/var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php第317行中的UnitOfWork->executeUpdates()
  • 在/var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php第355行的UnitOfWork->commit()
  • 在/var/www/issue/src/iTracker/UserBundle/Listener/UserGroupAmount.php第41行中的EntityManager->刷新()

这5个错误被循环,这导致了这个异常。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-07 09:09:46

调用作者建议的flush不是正确的解决方案。它将两次触发onFLush并在事务中创建不必要的保存点。

所有其他更改都可以使用computeChangeSetrecomputeSingleEntityChangeSetscheduleExtraUpdate方法对事件进行调度。

在与另一实体的情况下:

代码语言:javascript
运行
复制
public function preUpdate(PreUpdateEventArgs $args) {        
    $user = $args->getEntity();
    if($user instanceof \iTracker\UserBundle\Entity\User) {
        if($args->hasChangedField('userGroup')) {
            $old = $args->getOldValue('userGroup');
            $new = $args->getNewValue('userGroup');

            $oldOriginAmount = $old->getAmount();
            $newOriginAmount = $new->getAmount();

            $old->setAmount($old->getAmount() - 1);
            $uow->scheduleExtraUpdate($old, array(
                'amount' => array($oldOriginAmount, $old->getAmount())
            ));

            $new->setAmount($new->getAmount() + 1);
            $uow->scheduleExtraUpdate($new, array(
                'amount' => array($newOriginAmount, $new->getAmount())
            ));
        }
    }
}

不需要调用persist (因为在任何情况下都不会创建关联的实体,它们应该已经是持久的)。

票数 2
EN

Stack Overflow用户

发布于 2015-07-17 09:16:24

@meze是对的,在*刷新*事件中使用刷新将导致一个循环。

但是有一个快速的解决方法可以让您仍然这样做:$eventManager = $this -> em -> getEventManager();

代码语言:javascript
运行
复制
// Remove event, if we call $this->em->flush() now there is no infinite recursion loop!
$eventManager -> removeEventListener('onFlush', $this); 

// ...

// Re-attach since we're done
$eventManager -> addEventListener('onFlush', $this); 

见:Doctrine2事件侦听器:持久化onFlush()

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16980191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档