2013-07-01 41 views
0

Doctrine2是否支持從反方更改關聯的能力?如果不是開箱即用,是否有一個插件/擴展可以用來覆蓋這種行爲?Doctrine2中的反向關聯分配

這裏是什麼,我有一個例子:

Organization 
/** 
* @Id 
* @Column(type="integer") 
*/ 
    protected $id 

/** 
* @ManyToOne(targetEntity="Organization", inversedBy="children", cascade={"persist"}) 
* @JoinColumn(name="parent_org_id", referencedColumnName="id") 
*/ 
protected $parent; 

/** 
* @OneToMany(targetEntity="Organization", mappedBy="parent", cascade={"persist"}) 
*/ 
protected $children;  

回答

1

號學說2曲目協會通過持有端,當它試圖對你的實體的行爲的影響最小,但不希望添加這種功能。

跟蹤反面變化的標準方法是通過在實體上添加邏輯來更新自己的邊,從而確保它們保持同步。

在你的榜樣,你可以有的addChild,removeChild之和的setParent函數做這樣的事情:

public function addChild(Organization $child) 
{ 
    $this->children[] = $child; 
    $child->setParent($this); // < update the owning side 
} 

public function removeChild(Organization $child) 
{ 
    $this->children->removeElement($child); 
    $child->setParent(null); // < update the owning side 
} 

public function setParent(Organization $parent = null) 
{ 
    $this->parent = $parent; 
} 

你可以看到,現在有一個新的問題,必須始終使用addChild/removeChild之功能(即在反面進行更改)保持同步(或自己同步,作爲主叫方)。這導致你不得不制定一項政策,要麼呼叫者必須始終更新自己的方面,或反面。

可能使setParent功能也更新反側,但是你必須非常小心作爲很容易導致無限遞歸:

public function addChild(Organization $child) 
{ 
    $this->children[] = $child; 
    // safely update the owning side 
    if ($child->getParent() != $this) { 
     $child->setParent($this); 
    } 
} 

public function removeChild(Organization $child) 
{ 
    $this->children->removeElement($child); 
    // safely update the owning side 
    if ($child->getParent() == $this) { 
     $child->setParent(null); 
    } 
} 

public function setParent(Organization $parent = null) 
{ 
    $oldParent = $this->parent; 
    $this->parent = $parent; 
    // update the inverse side 
    if ($oldParent) { 
     $oldParent->removeChild($this); // will not call setParent 
    } 
    if ($this->parent) { 
     $this->parent->addChild($this); // will not call setParent 
    } 
} 
從增加的複雜性

除此之外,該方案例如,將很多孩子從一個父母移動到另一個父母時不理想,因爲removeChild需要線性時間,從而爲移動創建一個O(n^2)運行時間。