更新递归实体属性

时间:2014-05-15 19:41:58

标签: php symfony doctrine-orm

我有一个包含父/子项

的递归实体
  namespace Vendor\StructureBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Events;
use Gedmo\Mapping\Annotation as Gedmo;
/**
 * Vendor\StructureBundle\Entity\Structure
 * @Gedmo\Tree(type="nested")
 *
 * @ORM\Table(name="lowbi_structure")
 * @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
 * @ORM\HasLifecycleCallbacks()
 * @CustomAssert\ganttDate
 */
         class Structure {

              /**
               * @var integer $id
               *
               * @ORM\Column(name="id", type="integer")
               * @ORM\Id
               * @ORM\GeneratedValue(strategy="AUTO")
               */
              private $id;
    ...

              /**
               * @ORM\Column(name="title", type="string", length=64)
               */
              private $title;

              /**
               * @Gedmo\TreeParent
               * @ORM\ManyToOne(targetEntity="Structure", inversedBy="children",cascade={"persist"})
               * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
               */
              private $parent;
              /*
               * @ORM\OneToMany(targetEntity="Structure", mappedBy="parent",cascade={"persist","remove"})
               * @ORM\OrderBy({"lft" = "ASC"})
               */
              private $children;
    ...

          }

我希望更新"父母"当我坚持这个实体时。

/**
* Set prePersist
* 
* @ORM\PrePersist()
* @ORM\PreUpdate()
* 
*/
public function prePersist()
{
    $this->getParent()->setTitle('Foo');
}

问题是我的当前实体是持久的,但父实体不是。标题未保存。 如何保存父母的属性?

PS:我简化了代码。在现实世界中,我需要更新父开始日期/结束日期以适合孩子(项目管理树)

2 个答案:

答案 0 :(得分:0)

如果您之后只保存孩子,那么您在此处尝试执行的操作无法使用生命周期回调(即@PrePersist)。

Doctrine仅跟踪并保存对关系所属方的更改。

  

更新双向关联时,Doctrine仅检查   这些变化的双方之一。这被称为拥有方   协会。

因此,您不能通过仅保留子项来保持子项的父更新。

您可以在 this answer 和文档章节 Working with Associations 中找到有关反向和拥有方概念的更多信息。

要解决此问题...您可以保留父项而不是子项...或(而不是使用生命周期回调@PrePersist)创建一个将自动保留父项的事件侦听器。这通常是一种更好的做法,因为它使应用程序逻辑远离您的模型。

文档章节 How to Register Event Listeners and Subscribers 提供了帮助您入门的所有必要信息。

答案 1 :(得分:0)

我不知道为什么,但如果我在prePersist函数中返回 $ this ,那就是IT工作。

**
* Set prePersist
* 
* @ORM\PrePersist()
* @ORM\PreUpdate()
* 
*/
public function prePersist()
{
    //$this->getParent()->setTitle('Foo');
    return $this->getParent()->setTitle('Foo'); //solved this problem!!!!
}