【问题标题】:Get scheduled extra updates from Doctrine UnitOfWork从 Doctrine UnitOfWork 获取预定的额外更新
【发布时间】:2014-04-09 09:12:07
【问题描述】:

我有一个侦听 onFlush 事件的 Doctrine 事件侦听器。保存时,我使用它来更新实体上的 eTag。

我需要访问计划删除的实体,所以我可以访问它们的关联对象,但是:

我使用的是可软删除过滤器,因此实体实际上不在$uow->getScheduledEntityDeletions() 中,而是在$uow->extraUpdates 中,标记已删除标志已更改。

这个变量是私有的,我不知道有任何程序化的方式可以得到这个变化的通知。有什么想法吗?

private function updateIfRequired(OnFlushEventArgs $args)
{
    $em     = $args->getEntityManager();
    $uow    = $em->getUnitOfWork();



    // Entities either updated or just inserted
    $upsertedEntities = array_merge(

        $uow->getScheduledEntityUpdates(),
        $uow->getScheduledEntityInsertions()
    );

    foreach ($upsertedEntities as $entity) {

        if ($entity instanceof ETaggableInterface || $entity instanceof ETagRelatedInterface) {
            $this->updateETag($entity);
        }
    }

    // When soft-deleted, this and getScheduledEntityUpdates are both empty!
    $deletedEntities = $uow->getScheduledEntityDeletions();

    foreach ($deletedEntities as $entity) {

        $this->deletedEntities[spl_object_hash($entity)] = $entity;
        $this->updateETag($entity);
    }

}

【问题讨论】:

    标签: symfony doctrine-orm unit-of-work etag


    【解决方案1】:

    所以,这个问题的详细答案应该是这样的:

    收听 preSoftDelete 事件 (Symfony2 DoctrineExtensions preSoftDelete event call):

        tags:
            - { name: doctrine.event_listener, event: preSoftDelete }
    

    然后在你的监听器类中,添加以下方法:

    public function preSoftDelete(LifecycleEventArgs $args){
        $entity = $args->getEntity();
        $em = $args->getEntityManager();
    
        if ($entity instanceof ETaggableInterface || $entity instanceof ETagRelatedInterface) {
            $entity->updateEtag('foo'); // Was not clear what $this->updateEtag() do
    
            $em->persist($entity);
            $classMetadata = $em->getClassMetadata(get_class($entity));
            $em->getUnitOfWork()->computeChangeSet($classMetadata, $entity);
        }
    }
    

    这将更新实体,告诉它持久化,计算变化。

    【讨论】:

    • 不错。感谢分享。你是对的,$this->updateEtag() 是同一个类中的一个方法,我为了简洁而省略了。你可以在这里找到我最终实现的更详细的版本(粗略地说):gist.github.com/adamquaile/0733417e1d6a9c98ed27
    【解决方案2】:

    【讨论】:

    • 我确实寻找过,但没有找到。我实际上通过侦听其他生命周期事件以获取受影响的实体并在批处理 onFlush 中安排更新来解决它。将接受作为答案,因为这就是我想要的。
    猜你喜欢
    • 1970-01-01
    • 2013-05-25
    • 2016-06-07
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多