【问题标题】:Doctrine2 raises preFlush too many times (?)Doctrine2 多次提高 preFlush (?)
【发布时间】:2013-11-23 16:24:04
【问题描述】:

我刚刚注意到 Doctrine 事件系统的奇怪行为。在我读到的关于preFlush事件的文档中:

preFlush 先于EntityManager#flush() 调用

听起来不错。但是当我创建事件订阅者时,我发现有问题 - preFlush 发生了两次,而 onFlushpostFlush 只发生了一次(我假设 preFlush 也发生了一次)。

有趣的是,每次UnitOfWork 计算变更集时都会调用preFlush - 等于当前托管实体的数量。

这是一个简单的例子(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 工作不正确还是我还缺少其他东西?

【问题讨论】:

    标签: php database doctrine-orm doctrine entitymanager


    【解决方案1】:

    我不知道这是不是故意的,但这似乎是合乎逻辑的。 PreFlush 调用的数量与托管实体的数量相匹配,但可能是因为该方法旨在允许您强制执行实体的完整性。

    注意PostFlush 的调用次数没有增加。如果每个实体的数据在刷新时发生变化,那么每个实体都会再次调用PostFlush

    理想情况下,不带参数的$em-&gt;flush() 应该只在脚本执行结束时调用(或至少很少次)。为了确保在调用特定实体时对其进行处理和刷新,请将实体作为参数传递给flush 方法。

    【讨论】:

    • 如果 preFlush() 中的某些条件失败,是否有任何方法可以中止刷新操作?或者在不调用 ->flush() 的情况下调用 preFlush 侦听器?
    【解决方案2】:

    每次调用$em-&gt;flush() 都会触发preFlushpostFlush 仅在存在要提交的实际变更集时才会触发。有关如何更改此 postFlush 行为的讨论,请参阅 https://github.com/doctrine/doctrine2/pull/382

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多