2013-03-01 2 views
2

Я пытаюсь отключить событие сущности извне сущности в Doctrine 2. Каждый раз, когда мы вставляем новую запись в нашу таблицу, нужно запускать несколько операций с файлами, которые были реализованы в методе с аннотацией prePersist. Однако мне также нужно запустить некоторые приборы и пропустить часть операции с файлом в рамках тестирования. В основном я спрашиваю, можно ли отключить все события prePersist через диспетчер сущностей без изменения чего-либо в объекте.Doctrine 2 - отключить PrePersist извне объекта

Заранее спасибо.

ответ

1

Отключение lifecycle callbacks невозможно с помощью API ORM.

Проблема возникает из-за того, что external listeners are called after the entity's lifecycle callbacks are invoked, поэтому даже свойство переходного процесса, которое отключает обратный вызов (устанавливается внешним прослушивателем/подписчиком), не будет работать.

Рассмотрите возможность перемещения логики от сущности к внешнему слушателю/подписчику: таким образом вы получите гораздо большую гибкость, и вы сможете отключить описанное вами поведение, повторно используя статус, внутренний для слушателя/сам абонент.

// ... 

public function prePersist(LifecycleEventArgs $args) 
{ 
    if ($this->skipCondition($args->getEntity()) { 
     return; 
    } 

    $this->manipulate($args->getEntity()); 
} 

// ... 
+0

в prePersist рассуждений есть сущность и способны проверить поля, но как насчет постнагрузки? Я пытаюсь пропустить postLoad ... – Jekis

+0

'postLoad' является надежным для полей/столбцов, но не для ассоциаций. – Ocramius

8

Если вы нормально с полностью удалить обратные вызовы жизненного цикла, то вы можете просто пустой из обратных вызовов вручную. Это полезно в случае создания динамических приборов. Вы просто сделать это:

$this->em->getClassMetadata(get_class($object))->setLifecycleCallbacks(array()); 

Благодаря Джереми Микола (@jmikola) указал мне в правильном направлении.

4

JimTheDev's solution действительно хорошо работает.
В одном из моих тестовых классов у меня есть этот метод:

private function persistSkippingEvents($object, $manager) 
{ 
    // temporarily stores lifecycle events 
    $events = $manager->getClassMetadata(get_class($object))->lifecycleCallbacks; 

    // removes lifecycle events 
    $manager->getClassMetadata(get_class($object))->setLifecycleCallbacks(array()); 
    $manager->persist($object); 
    $manager->getClassMetadata(get_class($object))->setLifecycleCallbacks($events); 
} 
+1

взгляните на [это] (http://stackoverflow.com/questions/12738974/remove-doctrine-life-cycle-event-from-within-a-symfony2-controller) также – Matteo

Смежные вопросы