UnitOfWork pre update invoke causes some times fatal errors #4968

Closed
opened 2026-01-22 14:54:34 +01:00 by admin · 9 comments
Owner

Originally created by @ghost on GitHub (Jan 11, 2016).

Originally assigned to: @guilhermeblanco on GitHub.

I've the same problem like described in https://github.com/doctrine/doctrine2/issues/3468. Somehow the change set for the entity is gone while calling the commit function. I guess it will work if one changes the following line of code.

$this->listenersInvoker->invoke($class, Events::preUpdate, $entity, new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]), $preUpdateInvoke);

To use the method "getEntityChangeSet" to force to get an array. Because it does the same like before in a cleaner manner and one will always get an array back.

$this->listenersInvoker->invoke($class, Events::preUpdate, $entity, new PreUpdateEventArgs($entity, $this->em, $this->getEntityChangeSet($entity)), $preUpdateInvoke);

(1697293591/lib/Doctrine/ORM/UnitOfWork.php (L1052))

This is my first ticket creation for the doctrine2 project, I hope it will help to improve the project.

Originally created by @ghost on GitHub (Jan 11, 2016). Originally assigned to: @guilhermeblanco on GitHub. I've the same problem like described in https://github.com/doctrine/doctrine2/issues/3468. Somehow the change set for the entity is gone while calling the commit function. I guess it will work if one changes the following line of code. ``` php $this->listenersInvoker->invoke($class, Events::preUpdate, $entity, new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]), $preUpdateInvoke); ``` To use the method "getEntityChangeSet" to force to get an array. Because it does the same like before in a cleaner manner and one will always get an array back. ``` php $this->listenersInvoker->invoke($class, Events::preUpdate, $entity, new PreUpdateEventArgs($entity, $this->em, $this->getEntityChangeSet($entity)), $preUpdateInvoke); ``` (https://github.com/doctrine/doctrine2/blob/16972935917307c49c6a423edcc1fbb711e0d483/lib/Doctrine/ORM/UnitOfWork.php#L1052) This is my first ticket creation for the doctrine2 project, I hope it will help to improve the project.
admin added the Bug label 2026-01-22 14:54:34 +01:00
admin closed this issue 2026-01-22 14:54:35 +01:00
Author
Owner

@Ocramius commented on GitHub (Jan 11, 2016):

@sr-amueller the initial issue ( #3468 ) was closed due to lack of tests: can you reproduce the issue in isolation?

@Ocramius commented on GitHub (Jan 11, 2016): @sr-amueller the initial issue ( #3468 ) was closed due to lack of tests: can you reproduce the issue in isolation?
Author
Owner

@ghost commented on GitHub (Jan 11, 2016):

@Ocramius Not right now, but I will try to reproduce it the issue in isolation in the next few days.

@ghost commented on GitHub (Jan 11, 2016): @Ocramius Not right now, but I will try to reproduce it the issue in isolation in the next few days.
Author
Owner

@Ocramius commented on GitHub (Jan 11, 2016):

@sr-amueller thanks :-)

@Ocramius commented on GitHub (Jan 11, 2016): @sr-amueller thanks :-)
Author
Owner

@Bencsi commented on GitHub (Jan 29, 2016):

In my case the problem was, $em = $this->getDoctrine()->getManager(); inside a try block, I moved this line above the try block, problem solved. :)

@Bencsi commented on GitHub (Jan 29, 2016): In my case the problem was, `$em = $this->getDoctrine()->getManager();` inside a try block, I moved this line above the try block, problem solved. :)
Author
Owner

@dontub commented on GitHub (May 11, 2017):

I think this might happen when flush() is called a second time during a running flush. The foreach in executeUpdates() iterates over entityUpdates in the state when the loop was started so the current entityUpdates and entityChangeSets might not contain the entity, anymore. In that case the following code at the beginning of the loop would be a possible solution:

if (!isset($this->entityUpdates[$oid])) {
    continue;
}

As commented in 86cde3a that fix leads to another error.

Aside: I'm wondering why the preUpdate event occurs during the flush whereas prePersist und preRemove occur immediately when persist() or remove() is called.

@dontub commented on GitHub (May 11, 2017): I think this might happen when `flush()` is called a second time during a running flush. The `foreach` in `executeUpdates()` iterates over `entityUpdates` in the state when the loop was started so the current `entityUpdates` and `entityChangeSets` might not contain the entity, anymore. In that case the following code at the beginning of the loop would be a possible solution: ``` if (!isset($this->entityUpdates[$oid])) { continue; } ``` As commented in [86cde3a](https://github.com/doctrine/doctrine2/commit/86cde3a9dff818573971efb0b4ac54a45560ae0b) that fix leads to another error. Aside: I'm wondering why the preUpdate event occurs during the flush whereas prePersist und preRemove occur immediately when `persist()` or `remove()` is called.
Author
Owner

@apoorva-shah commented on GitHub (May 18, 2017):

I still got this error

Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::__construct() must be of the type array, null given, called in UnitOfWork.php on line 1060

In controller

removeExpireProducts();
$em->flush();

Inside my service:

function removeExpireProducts()
{
    foreach ($products as $product) {
      $em->remove($product);
    }
}

Please suggest.

@apoorva-shah commented on GitHub (May 18, 2017): I still got this error Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::__construct() must be of the type array, null given, called in UnitOfWork.php on line 1060 In controller ``` removeExpireProducts(); $em->flush(); ``` Inside my service: ``` function removeExpireProducts() { foreach ($products as $product) { $em->remove($product); } } ``` Please suggest.
Author
Owner

@Ocramius commented on GitHub (May 18, 2017):

I think this might happen when flush() is called a second time during a running flush.

Flushing inside a flush operation is not supported, so that scenario is pretty much invalid.

@Ocramius commented on GitHub (May 18, 2017): > I think this might happen when `flush()` is called a second time during a running flush. Flushing inside a flush operation is not supported, so that scenario is pretty much invalid.
Author
Owner

@apoorva-shah commented on GitHub (May 18, 2017):

Hello @Ocramius thanks, but i did not understand
Flushing inside a flush operation is not supported, so that scenario is pretty much invalid.
Can you explain more? how to avoid this error?

@apoorva-shah commented on GitHub (May 18, 2017): Hello @Ocramius thanks, but i did not understand Flushing inside a flush operation is not supported, so that scenario is pretty much invalid. Can you explain more? how to avoid this error?
Author
Owner

@lcobucci commented on GitHub (May 18, 2017):

@apoorva-shah EntityManager#flush() will commit the Unit of Work (UoW) which will then compute the changeset that needs to be applied to the persistence layer. Committing UoW changes in the middle of a commit causes inconsistencies and therefore is invalid.

You can read http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html for more information.

@lcobucci commented on GitHub (May 18, 2017): @apoorva-shah `EntityManager#flush()` will commit the [Unit of Work](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/architecture.html#the-unit-of-work) (UoW) which will then compute the changeset that needs to be applied to the persistence layer. Committing UoW changes in the middle of a commit causes inconsistencies and therefore is invalid. You can read http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html for more information.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4968