关联的教义 postLoad 事件

Posted

技术标签:

【中文标题】关联的教义 postLoad 事件【英文标题】:Doctrine postLoad event for associations 【发布时间】:2013-01-24 12:04:05 【问题描述】:

我目前有一个实体,我想在加载时稍微修改它。此修改将是一次性更改,然后将与实体一起保存在新字段中。

澄清我当前的目标:实体是一个“位置”,是嵌套集的一部分。它有一个名称、lft/rgt 值和一个 ID。我使用该实体执行的一项计算量很大的任务是获取完整的位置路径并将其显示为文本。例如,对于位置实体“滑铁卢”,我想显示为“滑铁卢|伦敦|英国”。这涉及遍历整个集合(到根节点)。

为了降低成本,我在 Location 实体上创建了一个新字段,可以用该值标记(并在修改位置(或树中的任何位置)名称时更新)。考虑到我的应用程序处于活动状态,我需要避免将其作为一次性进程运行,因为它会在数据库上产生相当密集的一次性命中,相反我想在每个位置应用此更新(没有该值)被加载。我认为 Doctrine 的 postLoad 事件机制对于实现这一点来说是完美的,但是..

位置实体不是由我的应用程序直接加载的,它们始终是关系的反面。考虑到这一点,以及学说的 postLoad 事件的事实:

不加载(允许访问)任何相关数据 仅因拥有实体而被解雇

我无法温和地进行这些修改。

有人对此有什么建议或经验吗?

【问题讨论】:

作为个人建议,我不会通过持久层中的奇特逻辑来处理这个问题。相反,构建一个代理调用您的实体并最终处理获取父项的聚合模型。这将适合您的服务层 【参考方案1】:

通过使用实体管理器上的 initializeObject() 方法,我能够在 postLoad 事件中加载关联的 Location 对象。

/**
 * Upon loading the object, if the location text isn't set, set it
 * @param \Doctrine\ORM\Event\LifecycleEventArgs $args
 */
public function postLoad(\Doctrine\ORM\Event\LifecycleEventArgs $args)

    $this->em = $args->getEntityManager();
    $entity = $args->getEntity();

    if ($entity instanceof \Entities\Location)
    
        if (is_null($entity->getPathText()))
        
            $entity->setPathText("new value");
            $this->em->flush($entity);
        
     elseif ($entity instanceof parent Entity)
    
        $location = $entity->getLocation();
        // This triggers the postLoad event again, but this time with Location as the parent Entity
        $this->em->initializeObject($location);
    

【讨论】:

以上是关于关联的教义 postLoad 事件的主要内容,如果未能解决你的问题,请参考以下文章

坚持时的教义关联完整性约束

教义加入多对多没有关联

Symfony2 教义关联映射错误处理

教义:在 OneToMany 关联中忽略了 mappedBy 的值

教义:以键作为关联实体值的结果

教义自引用关联映射(Symfony)