douxiangshi6568 2014-08-14 10:48
浏览 31

symfony2更新eventListener中的相关实体

We have three entities:

  1. MaterialAssigned
  2. Stock
  3. Job

MaterialAssigned holds three fields:

  1. Quantity (int)
  2. Relation with a Job Entity
  3. Relation with a Stock entity

We are try to write a preUpdate() on MaterialAssigned which takes old and new Quantity values, do some calculation and update the overall total quantity in the related Stock Entity. When we var_dump() values along our logic, everything seems to work as expected, however the related Stock entity never gets updated.

That's the relevant code from the EventListener:

public function preUpdate(PreUpdateEventArgs $eventArgs)
{
    $entity = $eventArgs->getEntity();
     if ($entity instanceof MaterialAssigned) {

        $changeArray = $eventArgs->getEntityChangeSet();
        $pre_quantity = $changeArray['quantity'][0];
        $post_quantity = $changeArray['quantity'][1];

        // Here we call the function to do the calculation, for testing we just use a fixed value
        $entity->getStock()->setTotal(9999);

        $em   = $eventArgs->getEntityManager();
        $uow  = $em->getUnitOfWork();
        $meta = $em->getClassMetadata(get_class($entity));
        $uow->recomputeSingleEntityChangeSet($meta, $entity);
    }
}
  • 写回答

1条回答 默认 最新

  • duanri1985 2014-08-14 16:17
    关注

    The issue here is that preUpdate is restricted by Doctrine to not allow any Entities to be updated from within this method. onFlush on the other hand does allow the update of Entities, and replaces the need for three separate methods (update, persist, remove).

    We then found the following guide which hints at a solution: Tobias Sjösten's guide

    Our code now looks like:

    public function onFlush(OnFlushEventArgs $args)
    {
        $this->em = $args->getEntityManager();
        $uow = $this->em->getUnitOfWork();
    
        // These collects an array of all the changes that are going to be flushed.
        // If you do not wish to see deleted entities just remove the line $uow->getScheduledEntityDeletions()
        $entities = array_merge(
            $uow->getScheduledEntityInsertions(),
            $uow->getScheduledEntityUpdates(),
            $uow->getScheduledEntityDeletions()
        );
    
        foreach ($entities as $entity) {
    
            if ($entity instanceof MaterialAssigned) {
    
                // This gets an array filled with the changes for the entire entity
                $changeArray = $uow->getEntityChangeSet($entity);
    
                $stock = $entity->getStock();
    
                // Here we call our function passing $changeArray.
                // This does some math and update the value. For simplicity we just
                // set the value manually in this example
                $stock->setTotal(9999);
    
                $md = $this->em->getClassMetadata('Northerncam\AppBundle\Entity\Stock');
                $uow->recomputeSingleEntityChangeSet($md, $stock);
            }
        }
    }
    

    This is the print_r() of $changeArray:

    array (size=1)
        'quantity' =>
            array (size=2)
                0 => int 10
                1 => int 50
    
    评论

报告相同问题?

悬赏问题

  • ¥15 制裁名单20240508芯片厂商
  • ¥20 易康econgnition精度验证
  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致