Doctrine 2.6.1:触发OnFlush事件时创建新实体报错
解决Doctrine 2.6.1中OnFlush事件创建新实体的报错问题
我之前升级Doctrine版本的时候也踩过一模一样的坑!2.6版本开始,Doctrine对*Unit of Work(UoW)*的内部状态管理做了严格调整,直接导致你原来在2.5里正常运行的代码报错。
问题根源
在Doctrine 2.5中,你手动调用$uow->computeChangeSet()的方式能正常工作,因为当时UoW对事件中的实体添加操作限制没那么严。但到了2.6.1,UoW在处理OnFlush事件的过程中,内部已经处于“变更计算中”的状态,手动介入变更集计算会打乱它的流程,触发状态冲突的报错。
修复后的代码
你只需要把手动计算变更集的代码替换成Doctrine官方推荐的scheduleForInsert方法就行,调整后的代码如下:
foreach ($uow->getScheduledEntityInsertions() as $entity) { if ($entity instanceof Site) { $siteStatus = new SiteStatusHistory(); $siteStatus->setSite($entity); $siteStatus->setStatus($entity->getBillingStatus()); $manager->persist($siteStatus); // 替换原有的computeChangeSet,改用scheduleForInsert将实体加入UoW队列 $uow->scheduleForInsert($siteStatus); } }
为什么这样改?
在Doctrine 2.6+的OnFlush事件流程里:
$manager->persist()只是把新实体纳入EntityManager的管理,但不会立刻把它加入当前UoW的待处理队列$uow->scheduleForInsert()会将这个新实体正式加入到UoW的待插入列表中,让UoW在后续的流程里自动处理它的变更集,完全符合新版本的内部逻辑,自然就不会报错了
另外补充一点:如果是在OnFlush事件里修改已存在的实体,那应该用$uow->recomputeSingleEntityChangeSet()替代旧的computeChangeSet,不过你的场景是创建新实体,所以用scheduleForInsert就足够解决问题啦。
内容的提问来源于stack exchange,提问作者RomulusED69
相关产品推荐
相关产品推荐

