理论postLoad事件协会 [英] Doctrine postLoad event for associations

查看:104
本文介绍了理论postLoad事件协会的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前拥有一个实体,我想在加载时略微修改。该修改将是一次性更改,然后将与实体一起持续在新的领域。



澄清我目前的目标:实体是一个位置并构成嵌套集的一部分。它有一个名称,lft / rgt值和Id。我用这个实体执行的一个计算上昂贵的任务是获取一个完整的位置路径并将其显示为文本。例如,我想将位置实体滑铁卢显示为滑铁卢|伦敦|英国。这涉及遍历整个集合(到根节点)。



为了降低成本,我在Location实体上创建了一个可以加上此值的新字段(并在当前位置(或任何树中的位置)名称被修改)。考虑到我的应用程序处于实时状态,我需要避免将其作为一个关闭进程运行,因为它会在数据库中产生相当大的一次性攻击,而是要将每个位置(不含该值)被加载。我假设Doctrine的postLoad事件机制将是完美的,但是实现这一点。



位置实体不是由我的应用程序直接加载,它们将始终是一个关系有了这个想法,以及这个原则的postLoad事件:




  • 不加载(允许访问)任何关联的数据

  • 只有拥有实体才能启动



我没有办法轻轻地进行这些修改。 >

任何人都有任何建议或经验?

解决方案

我能够通过在Entity Manager上使用initializeObject()方法在postLoad事件中加载相关的Location对象。

  / ** 
*加载对象后,如果位置文本未设置,请设置为
* @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();
//这会再次触发postLoad事件,但这次将Location作为父Entity
$ this-> em-> initializeObject($ location);
}
}


I currently have an entity which I would like to modify slightly upon load. This modification will be a one time change which will then be persisted in a new field along with the entity.

To clarify my current objective: The entity is a "Location" and forms part of a nested set. It has a name, lft/rgt values and an Id. One computationally expensive task I was performing with this entity was to fetch a full location path and display it as text. For example, with the location entity "Waterloo" I want to display as "Waterloo|London|United Kingdom". This involves traversing through the entire set (to the root node).

To reduce the cost of this I've created a new field on the Location entity that can be stamped with this value (and updated as/when the location (or any location within the tree) name is modified). Considering my application is in a live state I need to avoid running this as a one off process as it would incur quite an intensive one-time hit on the DB, instead I'd like to apply this update as and when each location (without that value) is loaded. I assumed Doctrine's postLoad event mechanism would be perfect for achieving this, however..

The Location entities are not loaded directly by my application, they will always be the inverse side of a relation. With this is mind, and the fact that doctrine's postLoad event:

  • Doesn't load (allow access to) any associated data
  • Is only fired for owning Entities

I have no way of gently making these modifications.

Anyone have any advice, or experience on this?

解决方案

I was able to load the associated Location objects within the postLoad event by using the initializeObject() method on the Entity Manager.

/**
 * 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事件协会的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆