creating an entity inside postUpdate event handler fails... sometimes #5766

Open
opened 2026-01-22 15:17:12 +01:00 by admin · 13 comments
Owner

Originally created by @hq9000 on GitHub (Nov 10, 2017).

Originally assigned to: @hq9000 on GitHub.

we have a transaction, some entities are changed inside it. We are subscribed to postUpdate event
to log that changes. The log is also based on Doctrine mapped class (LogEntry).

so, roughly speaking, for each postUpdate event we create a new LogEntry inside a postUpdate event handler

    $logEntry = $this->constructLogEntry($record);
    $this->em->persist($logEntry);
    $this->em->flush();

we've witnessed one case when it failed, although after that it works without any issues. So the problem must be floating.

the final error of that single failure is:

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

in stack, this exception is down the that flush we do in order for a new LogEntry to be saved.

Most of the time, everything works.

if there shall no be persists/flushes on postUpdate event, this must be stated in docs (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html)
however there's a warning only regarding preUpdate (in our case it's postUpdate).

also would appreciate any guidance on how to achive this without risking occasional failures.

Originally created by @hq9000 on GitHub (Nov 10, 2017). Originally assigned to: @hq9000 on GitHub. we have a transaction, some entities are changed inside it. We are subscribed to postUpdate event to log that changes. The log is also based on Doctrine mapped class (LogEntry). so, roughly speaking, for each postUpdate event we create a new LogEntry inside a postUpdate event handler $logEntry = $this->constructLogEntry($record); $this->em->persist($logEntry); $this->em->flush(); we've witnessed one case when it failed, although after that it works without any issues. So the problem must be floating. the final error of that single failure is: Type error: Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::__construct() must be of the type array, null given, called in ...\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 1060 in stack, this exception is down the that flush we do in order for a new LogEntry to be saved. Most of the time, everything works. if there shall no be persists/flushes on postUpdate event, this must be stated in docs (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html) however there's a warning only regarding preUpdate (in our case it's postUpdate). also would appreciate any guidance on how to achive this without risking occasional failures.
Author
Owner

@Ocramius commented on GitHub (Nov 10, 2017):

Flushes in lifecycle event listeners are not allowed in any case: please
consider sending a patch to the docs.

On 10 Nov 2017 17:05, "hq9000" notifications@github.com wrote:

we have a transaction, some entities are changed inside it. We are
subscribed to postUpdate event
to log that changes. The log is also based on Doctrine mapped class
(LogEntry).

so, roughly speaking, for each postUpdate event we create a new LogEntry
inside a postUpdate event handler

$logEntry = $this->constructLogEntry($record);
$this->em->persist($logEntry);
$this->em->flush();

we've witnessed one case when it failed, although after that it works
without any issues. So the problem must be floating.

the final error of that single failure is:

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

in stack, this exception is down the that flush we do in order for a new
LogEntry to be saved.

Most of the time, everything works.

if there shall no be persists/flushes on postUpdate event, this must be
stated in docs (http://docs.doctrine-project.org/projects/doctrine-orm/en/
latest/reference/events.html)
however there's a warning only regarding preUpdate (in our case it's
postUpdate).

also would appreciate any guidance on how to achive this without risking
occasional failures.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/6822, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakKTr8R4PwFyMvoAw1MbR0ix79JXkks5s1HRFgaJpZM4QZw7r
.

@Ocramius commented on GitHub (Nov 10, 2017): Flushes in lifecycle event listeners are not allowed in any case: please consider sending a patch to the docs. On 10 Nov 2017 17:05, "hq9000" <notifications@github.com> wrote: > we have a transaction, some entities are changed inside it. We are > subscribed to postUpdate event > to log that changes. The log is also based on Doctrine mapped class > (LogEntry). > > so, roughly speaking, for each postUpdate event we create a new LogEntry > inside a postUpdate event handler > > $logEntry = $this->constructLogEntry($record); > $this->em->persist($logEntry); > $this->em->flush(); > > we've witnessed one case when it failed, although after that it works > without any issues. So the problem must be floating. > > the final error of that single failure is: > > Type error: Argument 3 passed to Doctrine\ORM\Event\PreUpdateEventArgs::__construct() > must be of the type array, null given, called in > ...\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 1060 > > in stack, this exception is down the that flush we do in order for a new > LogEntry to be saved. > > Most of the time, everything works. > > if there shall no be persists/flushes on postUpdate event, this must be > stated in docs (http://docs.doctrine-project.org/projects/doctrine-orm/en/ > latest/reference/events.html) > however there's a warning only regarding preUpdate (in our case it's > postUpdate). > > also would appreciate any guidance on how to achive this without risking > occasional failures. > > — > You are receiving this because you are subscribed to this thread. > Reply to this email directly, view it on GitHub > <https://github.com/doctrine/doctrine2/issues/6822>, or mute the thread > <https://github.com/notifications/unsubscribe-auth/AAJakKTr8R4PwFyMvoAw1MbR0ix79JXkks5s1HRFgaJpZM4QZw7r> > . >
Author
Owner

@hq9000 commented on GitHub (Nov 10, 2017):

Flushes in lifecycle event listeners are not allowed in any case

what about persists?

@hq9000 commented on GitHub (Nov 10, 2017): > Flushes in lifecycle event listeners are not allowed in any case what about persists?
Author
Owner

@Ocramius commented on GitHub (Nov 10, 2017):

Mostly safe to perform in onFlush and preFlush, but not after that...

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On Fri, Nov 10, 2017 at 8:05 PM, hq9000 notifications@github.com wrote:

Flushes in lifecycle event listeners are not allowed in any case

what about persists?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/6822#issuecomment-343558963,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakCSKuEmL3bDaNnkIk_mN2XHzCCoqks5s1J6TgaJpZM4QZw7r
.

@Ocramius commented on GitHub (Nov 10, 2017): Mostly safe to perform in onFlush and preFlush, but not after that... Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ On Fri, Nov 10, 2017 at 8:05 PM, hq9000 <notifications@github.com> wrote: > Flushes in lifecycle event listeners are not allowed in any case > > what about persists? > > — > You are receiving this because you commented. > Reply to this email directly, view it on GitHub > <https://github.com/doctrine/doctrine2/issues/6822#issuecomment-343558963>, > or mute the thread > <https://github.com/notifications/unsubscribe-auth/AAJakCSKuEmL3bDaNnkIk_mN2XHzCCoqks5s1J6TgaJpZM4QZw7r> > . >
Author
Owner

@hq9000 commented on GitHub (Nov 10, 2017):

so what is the right way then to do some doctrine event handling involving creating entities?

Our plan B was to hook on postFlush and persist and flush there. After your last comment I'm not sure anymore.

@hq9000 commented on GitHub (Nov 10, 2017): so what is the right way then to do some doctrine event handling involving creating entities? Our plan B was to hook on postFlush and persist and flush there. After your last comment I'm not sure anymore.
Author
Owner

@Ocramius commented on GitHub (Nov 10, 2017):

You should hook into onFlush and do it there (without nested flush(), which doesn't work anyway)

@Ocramius commented on GitHub (Nov 10, 2017): You should hook into `onFlush` and do it there (without nested `flush()`, which doesn't work anyway)
Author
Owner

@hq9000 commented on GitHub (Nov 11, 2017):

Thanks, now trying your suggestion.

what about persists?

Mostly safe to perform in onFlush and preFlush

What do you mean by "mostly". What are circumstances they are not safe in on/preFlush?

@hq9000 commented on GitHub (Nov 11, 2017): Thanks, now trying your suggestion. > what about persists? > Mostly safe to perform in onFlush and preFlush What do you mean by "mostly". What are circumstances they are not safe in on/preFlush?
Author
Owner

@hq9000 commented on GitHub (Nov 11, 2017):

also, what if we do this log entries operations through it's own, log dedicated EntityManager - would it still be a problem if we persist/flush on this dedicated entity manager in lifecycle callbacks related to the "main" entity manager?

@hq9000 commented on GitHub (Nov 11, 2017): also, what if we do this log entries operations through it's own, log dedicated EntityManager - would it still be a problem if we persist/flush on this dedicated entity manager in lifecycle callbacks related to the "main" entity manager?
Author
Owner

@hq9000 commented on GitHub (Nov 12, 2017):

You should hook into onFlush and do it there (without nested flush(), which doesn't work anyway)

tried that an bumbed into another problem. It looks like there's a problem inserting these new onFlush-originating entities into the DB.

`An exception occurred while executing 'INSERT INTO audit_log_entries (.. ... ..) VALUES (?, ?, ?, ?, ?, ?, ?, ?)':

SQLSTATE[HY093]: Invalid parameter number: no parameters were bound`

relevant fragment of the stack:

at PDOStatement ->execute (null)
in vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOStatement.php at line 105
at PDOStatement ->execute (null)
in vendor\doctrine\dbal\lib\Doctrine\DBAL\Statement.php at line 168
at Statement ->execute ()
in vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php at line 281
at BasicEntityPersister ->executeInserts ()
in vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php at line 1014
at UnitOfWork ->executeInserts (object(ClassMetadata))
in vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php at line 378
at UnitOfWork ->commit (null)
in vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php at line 356
at EntityManager ->flush (null)
in var\cache\dev\appDevDebugProjectContainer.php at line 5967

what can be wrong here?

@hq9000 commented on GitHub (Nov 12, 2017): > You should hook into onFlush and do it there (without nested flush(), which doesn't work anyway) tried that an bumbed into another problem. It looks like there's a problem inserting these new onFlush-originating entities into the DB. `An exception occurred while executing 'INSERT INTO audit_log_entries (.. ... ..) VALUES (?, ?, ?, ?, ?, ?, ?, ?)': SQLSTATE[HY093]: Invalid parameter number: no parameters were bound` relevant fragment of the stack: at PDOStatement ->execute (null) in vendor\doctrine\dbal\lib\Doctrine\DBAL\Driver\PDOStatement.php at line 105 at PDOStatement ->execute (null) in vendor\doctrine\dbal\lib\Doctrine\DBAL\Statement.php at line 168 at Statement ->execute () in vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\Entity\BasicEntityPersister.php at line 281 at BasicEntityPersister ->executeInserts () in vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php at line 1014 at UnitOfWork ->executeInserts (object(ClassMetadata)) in vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php at line 378 at UnitOfWork ->commit (null) in vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php at line 356 at EntityManager ->flush (null) in var\cache\dev\appDevDebugProjectContainer.php at line 5967 what can be wrong here?
Author
Owner

@lcobucci commented on GitHub (Nov 26, 2017):

@hq9000 things here are a bit confusing, could you send us a failing test case that reproduces that behaviour? It would help us a lot to identify and fix the issue you're describing.

You can find examples on 388afb46d0/tests/Doctrine/Tests/ORM/Functional/Ticket

@lcobucci commented on GitHub (Nov 26, 2017): @hq9000 things here are a bit confusing, could you send us a failing test case that reproduces that behaviour? It would help us a lot to identify and fix the issue you're describing. You can find examples on https://github.com/doctrine/doctrine2/tree/388afb46d0cb3ed0c51332e8df0de9e942c2690b/tests/Doctrine/Tests/ORM/Functional/Ticket
Author
Owner

@lcobucci commented on GitHub (Nov 26, 2017):

@hq9000 also, why do you want to couple this to the ORM event system? Using your own events should be simpler (but please don't call flush() more than once on a single operation).

@lcobucci commented on GitHub (Nov 26, 2017): @hq9000 also, why do you want to couple this to the ORM event system? Using your own events should be simpler (but please don't call `flush()` more than once on a single operation).
Author
Owner

@razbakov commented on GitHub (Sep 6, 2018):

Same problem as #7387

@razbakov commented on GitHub (Sep 6, 2018): Same problem as #7387
Author
Owner

@aivus commented on GitHub (Oct 12, 2018):

Flushes in lifecycle event listeners are not allowed in any case: please
consider sending a patch to the docs.

What about throwing some exception/warning in case of using flush inside flush than?

@aivus commented on GitHub (Oct 12, 2018): > Flushes in lifecycle event listeners are not allowed in any case: please consider sending a patch to the docs. What about throwing some exception/warning in case of using `flush` inside `flush` than?
Author
Owner

@Ocramius commented on GitHub (Oct 12, 2018):

Send a patch 👌

On Fri, 12 Oct 2018, 11:37 Ilya Antipenko, notifications@github.com wrote:

Flushes in lifecycle event listeners are not allowed in any case: please
consider sending a patch to the docs.

What about throwing some exception/warning in case of using flush inside
flush than?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/6822#issuecomment-429266914,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakL-a9shc3CH0vZlHWCfDrR1B5Lr1ks5ukGLEgaJpZM4QZw7r
.

@Ocramius commented on GitHub (Oct 12, 2018): Send a patch 👌 On Fri, 12 Oct 2018, 11:37 Ilya Antipenko, <notifications@github.com> wrote: > Flushes in lifecycle event listeners are not allowed in any case: please > consider sending a patch to the docs. > > What about throwing some exception/warning in case of using flush inside > flush than? > > — > You are receiving this because you commented. > Reply to this email directly, view it on GitHub > <https://github.com/doctrine/doctrine2/issues/6822#issuecomment-429266914>, > or mute the thread > <https://github.com/notifications/unsubscribe-auth/AAJakL-a9shc3CH0vZlHWCfDrR1B5Lr1ks5ukGLEgaJpZM4QZw7r> > . >
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5766