我刚刚注意到 Doctrine 事件系统的奇怪行为。在我读到的关于preFlush
事件的文档中:
preFlush
EntityManager#flush()
在其他任何事情之前调用
听起来不错。但是当我创建事件订阅者时,我发现出了点问题——preFlush
发生了两次,onFlush
而且postFlush
只发生了一次(我假设这preFlush
也发生了一次)。
有趣的preFlush
是,每次UnitOfWork
计算变更集时都会调用 - 等于当前管理的实体的数量。
这是一个简单的例子(Doctrine 2.4,我没有使用 Symfony):
// event subscriber class:
class Subscriber implements EventSubscriber {
public function getSubscribedEvents() {
return array(Events::preFlush, Events::onFlush, Events::postFlush);
}
public function preFlush() {
echo '********** PRE FLUSH ***********' . "\n";
}
public function onFlush() {
echo '********** ON FLUSH ***********' . "\n";
}
public function postFlush() {
echo '********** POST FLUSH ***********' . "\n";
}
}
// test:
$em->getEventManager()->addEventSubscriber(new Subscriber());
for($i = 0; $i < 5; $i++) {
echo 'i = ' . $i . "\n";
$u = new Unit(); // Unit is sample entity - very simple one with no associations
$u->setName('unit');
$u->setSymbol('u');
$em->persist($u);
$em->flush();
}
产生输出:
i = 0
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** ON FLUSH ***********
********** POST FLUSH ***********
i = 1
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** ON FLUSH ***********
********** POST FLUSH ***********
i = 2
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** ON FLUSH ***********
********** POST FLUSH ***********
i = 3
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** ON FLUSH ***********
********** POST FLUSH ***********
i = 4
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** PRE FLUSH ***********
********** ON FLUSH ***********
********** POST FLUSH ***********
因此preFlush
,每个托管实体(包括新实体)调用一次 +EntityManager
实际刷新时调用一次。
在我看来preFlush
,每个操作都应该调用一次EntityManager#flush()
事件(就像其他刷新事件一样)。
我发现产生这种行为的代码:https ://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L536
这是我的问题:我错了,Doctrine 工作不正确还是我还缺少其他东西?