我目前有一个实体,我想在加载时稍微修改一下。此修改将是一次性更改,然后将与实体一起保留在新字段中。
澄清我当前的目标:实体是“位置”并构成嵌套集的一部分。它有一个名称,lft / rgt值和一个Id。我使用此实体执行的一项计算成本高昂的任务是获取完整的位置路径并将其显示为文本。例如,对于位置实体“滑铁卢”,我想显示为“滑铁卢|伦敦|英国”。这涉及遍历整个集合(到根节点)。
为了降低成本,我在Location实体上创建了一个新字段,该字段可以使用此值标记(并在/修改位置(或树中的任何位置)名称时更新)。考虑到我的应用程序处于实时状态,我需要避免将其作为一个关闭过程运行,因为它会对数据库产生相当密集的一次性命中,而是我想在每个位置应用此更新(不带该值已加载。我认为Doctrine的postLoad事件机制对于实现这一目标是完美的,但是..
我的应用程序不会直接加载位置实体,它们将始终是关系的反面。这是思想,以及教义的postLoad事件:
我无法轻轻地进行这些修改。
任何人对此都有任何建议或经验吗?
答案 0 :(得分:6)
我可以使用实体管理器上的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);
}
}