2

私はイベントリスナーを持っていますpreUpdate

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 の 6123 行目 /var/www/issue/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/ の ErrorHandler->handleFatal() で/var/www/issue/app/cache/dev/classes.php の NormalizerFormatter->normalize() の 0 行目 /var/www/issue/app/cache/ の LineFormatter->normalize() の 6198 行目dev/classes.php /var/www/issue/app/cache/dev/classes.php の NormalizerFormatter->format() の 6112 行目 /var/www/issue/app/ の LineFormatter->format() の 6172 行目cache/dev/classes.php /var/www/issue/app/cache/dev/classes.php の AbstractProcessingHandler->handle() の 6320 行目 /var/www/issue/ の Logger->addRecord() の 6646 行目/var/www/issue/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger の Logger->debug() の app/cache/dev/classes.php 行 6710。php /var/www/issue/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php の DbalLogger->log() の 72 行目 /var/ の DbalLogger->startQuery() の 50 行目www/issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php /var/www/issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/ の LoggerChain->startQuery() の 50 行目Connection.php /var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php の Connection->executeUpdate() の 774 行目 /var/ の BasicEntityPersister->_updateTable() の 447 行目www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php 行 357 の BasicEntityPersister->update() in /var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/ UnitOfWork.php 984 行目の UnitOfWork->/var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php の executeUpdates() 行 317 at UnitOfWork->commit() in /var/www/issue/vendor/doctrine/orm/lib /Doctrine/ORM/EntityManager.php 355 行目 EntityManager->flush() の /var/www/issue/src/iTracker/UserBundle/Listener/UserGroupAmount.php 41 行目とこれ

  • /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->flush() で

この 5 つのエラーがループし、この例外が発生します

4

2 に答える 2

2

flush著者が提案した呼び出しは正しい解決策ではありません。これは onFLush を 2 回起動し、トランザクションで不要なセーブポイントを作成します。

computeChangeSet追加のすべての変更は、 、recomputeSingleEntityChangeSetおよびscheduleExtraUpdateメソッドを使用してイベントでスケジュールできます。

別のエンティティの場合:

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は必要ありません (関連付けられたエンティティはどのイベントでも作成されないため、それらは既に永続化されているはずです)。

于 2013-06-07T09:09:46.530 に答える