0

I have setup a doctrine EntityListener. I need to execute some code in the postRemove event which must be out of any doctrine transaction. However:

public function postRemove(Image $image, LifecycleEventArgs $event)
{
    $isActive = $event->getEntityManager()->getConnection()->isTransactionActive();
    dump($isActive);
}

always dumps true.

No matter if I commit or flush inside the postRemove() method; I tried starting transaction in preRemove() and committing it in postRemove(), but that doesn't help.

Question: Is there a way to prevent Doctrine from wrapping postRemove() into transaction? If no, what is the best way for me to execute code which would be out of transaction? I don't care if it happens immediately or on kernel terminate, as long as it eventually happens.

I have an idea to create a destructor method in the EntityListener, and run the code when Listener destructs, but I don't know how reliable that would be. Maybe there are other (better) options?

thanks!

Karolis
  • 2,580
  • 2
  • 16
  • 31

1 Answers1

1

Sounds like you want to flush or persist, which is not something you want to do in a postRemove event.

From the docs:

Changes in here are not relevant to the persistence in the database, but you can use these events to alter non-persistable items, like non-mapped fields, logging or even associated classes that are not directly mapped by Doctrine.

So this event is not intended for performing operations with the entitymanager.

Use an onFlush listener instead. You can catch instances of your removed entity and perform appropriate actions. Read the documentation carefully, especially the The following restrictions apply to the onFlush event section

http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/events.html#onflush

Richard
  • 4,079
  • 1
  • 14
  • 17
  • The docs say that calling EntityManager::flush() inside onFlush event is also a bad idea. My problem is: When persisting a new image, I want to create several formats of that image, save those formats to the filesystem, and have references (rows) to those files inside another table. In order not to have inconsistencies between filesystem and database, I need to flush after every fs write operation. But it turns out I can't flush neither in pre/postPersist, nor in onFlush? – Karolis Mar 29 '16 at 08:51
  • Maybe having all of this work done inside EntityListener is a bad idea after all? – Karolis Mar 29 '16 at 09:19
  • You don't need to call flush, you use the unitofwork to make changes and persist, then recompute change set, done. here's an example from another question I answered: http://stackoverflow.com/questions/30734814/persisting-other-entities-inside-preupdate-of-doctrine-entity-listener/30741471#30741471 - this works, I use it in live production systems. – Richard Mar 29 '16 at 18:55