Reputation: 489
We have three entities:
MaterialAssigned
holds three fields:
Job
EntityStock
entityWe 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);
}
}
Upvotes: 0
Views: 888
Reputation: 489
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
Upvotes: 1