我有eventlistener 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行 ErrorHandler-> handleFatal()in /var/www/issue/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php NormalizerFormatter中的第0行 - > normalize()in /var/www/issue/app/cache/dev/classes.php第6198行 /var/www/issue/app/cache/dev/classes.php中的LineFormatter-> normalize() NormalizerFormatter-> format()中的第6112行 /var/www/issue/app/cache/dev/classes.php第6172行 /var/www/issue/app/cache/dev/classes.php中的LineFormatter-> format() 第6320行在AbstractProcessingHandler-> handle()中 /var/www/issue/app/cache/dev/classes.php第6646行 Logger-> addRecord()在/var/www/issue/app/cache/dev/classes.php中 6710在Logger-> debug()中 /var/www/issue/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php DbalLogger的第72行 - > log()in /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 LoggerChain的第50行 - > startQuery()in /var/www/issue/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php 在Connection-> executeUpdate()中的第774行 /var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php 在BasicEntityPersister-> _updateTable()中的第447行 /var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php BasicEntityPersister-> update()中的第357行 /var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php UnitOfWork的第984行 - > executeUpdates()in /var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php UnitOfWork的第317行 - > commit()in /var/www/issue/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php EntityManager的第355行 - > flush() /var/www/issue/src/iTracker/UserBundle/Listener/UserGroupAmount.php 第41行 这个
并且这5个错误被循环,导致此异常
答案 0 :(得分:2)
调用作者建议的flush
不是正确的解决方案。它将触发onFLush两次并在事务中创建不需要的保存点。
可以使用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
(因为在任何情况下都不会创建关联的entites,它们应该已经持久)。
答案 1 :(得分:2)
@meze是对的,在 * Flush * 事件中使用 flush 会导致循环。
但是有一个快速的解决方法可以让你做到这一点: $ eventManager = $ this - > em - > getEventManager();
// 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 Event Listener: persisting in onFlush() | Benedikt Wolters