我正在尝试从Doctrine 2中的实体外部禁用实体事件。每次我们在表中插入新记录时,都需要运行很少的文件操作,这些操作已在带有prePersist注释的方法中实现。但是,我还需要运行一些数据夹具并跳过文件操作部分作为测试的一部分。基本上我问是否可以通过实体管理器禁用所有prePersist事件而不改变实体中的任何内容。
提前致谢。
答案 0 :(得分:10)
如果您可以完全删除生命周期回调,那么您可以手动清空回调。这在动态夹具生成的情况下很有用。你只需这样做:
$this->em->getClassMetadata(get_class($object))->setLifecycleCallbacks(array());
感谢Jeremy Mikola(@jmikola)指出我正确的方向。
答案 1 :(得分:5)
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);
}
答案 2 :(得分:2)
使用ORM API无法禁用lifecycle callbacks。
问题来自于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());
}
// ...