Если вам нужно сохранить дополнительные объекты, обработчик postPersist или postUpdate в Doctrine, к сожалению, не подходит для правильного места. с той же самой проблемой сегодня, как мне нужно, чтобы сгенерировать записи сообщений в этом обработчике.
проблема на данный момент является то, что обработчик postPersist называется во флеш событий, а не после. Таким образом, вы не можете сохраняйте дополнительные объекты здесь, так как они не будут очищаться после этого. Кроме того, вы не можете вызывать флеш во время обработчика postPersist, поскольку это может привести к записи в ducplicate (как вы уже испытали).
Один путь использует обработчик onFlush от доктрины, описываемые здесь: http://doctrine-orm.readthedocs.org/en/latest/reference/events.html#onflush
Это просто проблематично, если вам нужно вставленные идентификаторы объекта базы данных, поскольку объект еще не был написан на базы данных в этом обработчике. Если вам не нужны эти идентификаторы, вы в порядке с событиемFlush в доктрине.
Для меня решение было немного иным. В настоящее время я работаю над проектом symfony2 и нуждаюсь в идентификаторах вставленных объектов базы данных (для обратных вызовов и обновлений позже).
Я создал новую службу в symfony2, которая в основном просто действует как очередь для моих сообщений. Во время обновления postPersist я просто заполняю записи в очереди. У меня есть другой обработчик, зарегистрированный на kernel.response
, который затем берет эти записи и сохраняет их в базе данных. (Что-то по этой теме: http://symfony.com/doc/current/cookbook/service_container/event_listener.html)
Надеюсь, я не отвлекся от темы здесь, но поскольку с ней я действительно боролся, я надеюсь, что некоторые люди могут найти это полезным.
Записи службы для этого являются:
amq_messages_chain:
class: Acme\StoreBundle\Listener\AmqMessagesChain
amqflush:
class: Acme\StoreBundle\Listener\AmqFlush
arguments: [ @doctrine.orm.entity_manager, @amq_messages_chain, @logger ]
tags:
- { name: kernel.event_listener, event: kernel.response, method: onResponse, priority: 5 }
doctrine.listener:
class: Acme\StoreBundle\Listener\AmqListener
arguments: [ @logger, @amq_messages_chain ]
tags:
- { name: doctrine.event_listener, event: postPersist }
- { name: doctrine.event_listener, event: postUpdate }
- { name: doctrine.event_listener, event: prePersist }
Вы не можете использовать doctrine.listener
для этого, так как это приводит к круговой зависимости (как вам нужно диспетчер сущностей для службы, но менеджер объект нуждается в обслуживании ....)
Это работало как шарм. Если вам нужна дополнительная информация об этом, не стесняйтесь спрашивать, я рад добавить к этому несколько примеров.
Thx! Можете ли вы дать мне ссылку на документацию об этом событии? В этом методе действительно разрешен флеш? – nucleartux
Я не могу найти ссылку в документации, я нашел ее в коде ([UnitOfWork :: commit()] (https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/ UnitOfWork.php # L245)). Эти события запускаются в самом начале и в конце флеша, поэтому его можно снова сбросить (я попытался). –
Имеет ли postFlush что-нибудь в getScheduledEntityInsertions(). Если это так, я не нахожу его. Это пусто для меня; Я думаю, потому что вставки уже произошли. –