我们有三个实体:
MaterialAssigned
包含三个字段:
Job
实体的关系Stock
实体的关系我们尝试在MaterialAssigned上写一个preUpdate()
,其中包含新旧Quantity
值,进行一些计算并更新相关Stock
实体中的总总数量。
当我们在逻辑中var_dump()
值时,一切似乎都按预期工作,但相关的Stock
实体永远不会更新。
这是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);
}
}
答案 0 :(得分:1)
此处的问题是,preUpdate
受到Doctrine限制,不允许在此方法中更新任何实体。另一方面,onFlush
允许更新实体,并取代了对三种不同方法(更新,持久,删除)的需求。
然后我们找到了以下指南,提示解决方案:Tobias Sjösten's guide
我们的代码现在看起来像:
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()
的{{1}}:
$changeArray