symfony2更新eventListener中的相关实体

symfony2更新eventListener中的相关实体

本文介绍了symfony2更新eventListener中的相关实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有三个实体:


  1. MaterialAssigned

  2. Stock

  3. 工作

MaterialAssigned 包含三个字段:


  1. 数量(int)

  2. 工作的关系实体

  3. 股票实体

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



的关系

我们正在尝试在MaterialAssigned上编写一个 preUpdate(),它需要使用新的 Quantity 值,并做一些计算并更新相关 Stock 实体的总数量。
当我们按照逻辑选择 var_dump()值时,一切似乎都按预期工作,但是相关的 Stock 实体永不更新。

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.

这是EventListener的相关代码:

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);
    }
}


推荐答案

此处的问题是 preUpdate 受Doctrine的限制,不允许在此方法内更新任何实体。另一方面, onFlush 确实允许更新实体,并且不需要三种单独的方法(更新,持久性,删除)。

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);
        }
    }
}

这是 print_r() of $ changeArray

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

这篇关于symfony2更新eventListener中的相关实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-27 21:06