更新递归实体属性


Update Recursive entity property

我有一个包含父/子项的递归实体

  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:我简化了代码。在现实世界中,我需要更新父开始日期/结束日期,以适应子(项目管理树)

你在这里想做的是不可能与一个生命周期回调(即@PrePersist),如果你只保存孩子之后。

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

当一个双向关联被更新时,Doctrine只检查这是双方的变化之一。这就是所谓的拥有方协会。

因此,你不能通过只持久化子进程来持久化父进程的更新。

你可以在这个答案和文档章节使用关联中找到更多关于逆侧和拥有侧概念的信息。

要解决这个问题…你可以持久化父类而不是子类……或者(而不是使用生命周期回调@PrePersist)创建一个事件侦听器,它将自动持久化父对象。这通常是一种更好的实践,因为它使应用程序逻辑脱离了模型。

文档章节如何注册事件侦听器和订阅者提供了所有必要的信息让你开始。

我不知道为什么,但是如果我在prePersist函数中返回$this, IT WORKS.

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