2016-12-04 2 views
-1

Я потратил 3 часа, пытаясь поделиться в социальных сетях некоторыми ссылками на PostPersist callback. Но, ссылки дали мне 404 error на страницах социальной сети. Я просто понял, что данные, которые я покраснел, на самом деле не существовали, когда был вызван обратный вызов PostPersist. Но в контроллере после entity->flush() я использовал тот же код, тогда ссылки работают нормально.Зачем использовать PostPersist в Symfony Doctrine

Я хотел бы знать, почему именно люди используют

/** 
* @ORM\PostPersist 
*/ 

обратного вызова.

+3

Что имеет свою историю из сайтов социальных сетей общего с вопросом о том, почему вы должны использовать PostPersist? Используйте PostPersist для отправки почты пользователю после создания сущности, поэтому он основан на событии. Поэтому вам не нужно делать это после каждого флеша, внутри каждого контроллера, который создает для вас этот объект. – Kwido

+0

Согласен, в случае, если это событие, происходящее при каждом сохранении данного объекта, рассмотрит возможность использования [пользовательского подписчика событий] (http://symfony.com/doc/current/doctrine/event_listeners_subscribers.html). Они более гибкие, чем любое событие обратного вызова. – ferdynator

+0

@ Kwido Пример социальной сети - объяснить, что данные еще не вставлены в базу данных во время обратного вызова PostPersist. Но данные были вставлены в базу данных после вызова flush(). – user3502626

ответ

2

От Doctrine2 documentation:

postPersist - Событие postPersist происходит для объекта после того, как объект был достигнут упорным. Он будет вызываться после операций вставки базы данных. Сгенерированные значения первичного ключа доступны в событии postPersist.

Но мы должны принять во внимание, что Doctrine2 вызывает транзакцию неявно по умолчанию. В этом подходе транзакция заканчивается, когда вы используете flush() в вашем менеджере сущностей. Вот почему вы не можете видеть данные в своей базе данных, если вы не скрываете диспетчер объектов. EntityManager # flush() - это когда транзакция начинается и заканчивается. Тем не менее у нас также есть возможность вызывать транзакцию явно, но она также не позволит вам видеть данные в базе данных между началом транзакции, сохранением объекта и фиксацией транзакции.

Фактически вы не можете опускать транзакции в Doctrine2, поэтому вы не можете ожидать, что ваши данные будут видны сразу после продолжения действия при возникновении события PostPersist.

Для этого вам необходимо использовать событие PostFlush.

Postperist в моей реальной жизни опыт используется, например, для:

  1. Создание данных, зависящих от созданного объекта (т.е. автоматические переводы, автоматические даты, некоторые конкретные обновления отношений)
  2. отправить уведомления другие события
  3. отправить электронную почту

Я надеюсь, что это помогает.

EDIT
Взгляните на примеры onFlush события, где вы можете увидеть примеры того, как пройти через единицу работы, чтобы добраться до вашего объекта. onFlush examples

работать только на конкретном объекте просто использовать:

if ($entity instanceof Product) { 
     // do something with the YourEntityName 
} 
+0

Проблема в том, что Doctrine2 говорит: postFlush - событие postFlush происходит в конце операции очистки. ** Это событие не является обратным вызовом жизненного цикла. ** – user3502626

+0

И ваши примеры для Postpersist в порядке. Кроме того, я действительно не согласен отправлять электронное письмо до того, как данные будут вставлены в базу данных. – user3502626

+0

@ user3502626 взгляните на мой EDIT. –