【发布时间】:2015-05-14 14:43:05
【问题描述】:
假设我有一个这样的实体
class FooEntity
{
$id;
//foreign key with FooEntity itself
$parent_id;
//if no parent level =1, if have a parent without parent itself = 2 and so on...
$level;
//sorting index is relative to level
$sorting_index
}
现在我想在delete 和edit 上更改此实体的级别和sorting_index。
所以我决定利用@987654325@ 并且我做了类似的事情
class FooListener
{
public function preUpdate(Foo $entity, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$this->handleEntityOrdering($entity, $em);
}
public function preRemove(Foo $entity, LifecycleEventArgs $args)
{
$level = $entity->getLevel();
$cur_sorting_index = $entity->getSortingIndex();
$em = $args->getEntityManager();
$this->handleSiblingOrdering($level, $cur_sorting_index, $em);
}
private function handleEntityOrdering($entity, $em)
{
error_log('entity to_update_category stop flag: '.$entity->getStopEventPropagationStatus());
error_log('entity splobj: '.spl_object_hash($entity));
//code to calculate new sorting_index and level for this entity (omitted)
$this->handleSiblingOrdering($old_level, $old_sorting_index, $em);
}
}
private function handleSiblingOrdering($level, $cur_sorting_index, $em)
{
$to_update_foos = //retrieve from db all siblings that needs an update
//some code to update sibling ordering (omitted)
foreach ($to_update_foos as $to_update_foo)
{
$em->persist($to_update_foo);
}
$em->flush();
}
}
这里的问题很清楚:如果我坚持一个Foo 实体,preUpdate()(进入handleSiblingOrdering 函数)触发器会被引发,这会导致无限循环。
我的第一个想法是在我的实体中插入一个特殊变量来防止这种循环:当我开始同级更新时,会设置该变量并在执行更新代码之前检查。这对preRemove() 来说就像一个魅力,但对preUpdate() 来说却不是。
如果您注意到我正在记录 spl_obj_hash 以了解此行为。令人惊讶的是,我可以看到在 preRemove() 之后传递给 preUpdate() 的 obj 是相同的(因此设置“状态标志”很好)但在 preUpdate() 之后传递给 preUpdate() 的对象不是一样的。
所以...
第一个问题
有人可以指出我处理这种情况的正确方向吗?
第二个问题
如果引发两个相似事件,为什么教义需要生成不同的对象?
【问题讨论】:
标签: symfony doctrine-orm