2012-11-15 82 views
2

我有兩個實體:一個Person和一個Address如何刪除可能處於「OneToMany」關係的實體

  • 一個Person可以有一個Address
  • Address可以從Person生活自給自足。

I'have創建這樣的關係:

地址

/** 
* @ORM\OneToMany(targetEntity="Person", mappedBy="address", cascade={"detach"}) 
*/ 
protected $persons; 

/** 
* @ORM\ManyToOne(targetEntity="Address", inversedBy="persons", cascade={"detach"}) 
* @ORM\JoinColumn(name="address_id", referencedColumnName="id") 
*/ 
protected $address; 

當我現在嘗試刪除Address是相關到Person它的結果,當然,在「完整性約束衝突」。我怎樣才能告訴學說detachPerson。如果在兩者上嘗試使用cascade={"detach"}但沒有任何反應。

+0

'detach'和'delete'操作(顯然)有區別。我假設你想從數據庫中物理刪除記錄,對吧? –

+0

其實我想刪除物理地址,重置'Person'中的引用。 – insertusernamehere

+0

好的,我添加了應該適合您的問題的答案... –

回答

5

人:

/** 
* @ORM\ManyToOne(targetEntity="Address", inversedBy="persons") 
* @ORM\JoinColumn(name="address_id", referencedColumnName="id", onDelete="SET NULL") 
*/ 
protected $address; 

地址:

/** 
* @ORM\OneToMany(targetEntity="Person", mappedBy="address", cascade={"all"}) 
*/ 
protected $persons; 

這種設置完全適用於我。當你刪除地址時,人將在address_id中得到NULL。級聯全部地址也將保存新的人,如果你這樣做:

$address->setPersons(
    array($person1, $person2) 
) ; 

其中$的人將是:

$person1 = new Person() ; 
$person1->setName(....) ; 

在這種情況下不能正常工作,請從控制器或發送代碼單元測試。它應該只是最基本的代碼;如果你使用地址,你只需堅持地址實體。同一個人實體。你不需要堅持這兩個,教條將照顧到這一點。

+0

這將是一個非常簡單的解決方案。 :)當我用你的代碼更新我的代碼時,碰巧當我刪除一個Address時,Person也被刪除了。哎呀。 – insertusernamehere

+1

嘗試刪除cascade = {「all」}或放置cascade = {「persist」}。你的控制器代碼是什麼,也許你在那裏有一些錯誤? – Zeljko

+0

這會再次引發良好的舊*違規*。 :)我已通過刪除「地址」動作更新了問題。 – insertusernamehere

1

可以刪除它是這樣的:關於$person->setAddress(NULL)

$id = ...; #some id 
$personRepository = $this->getDoctrine()->getRepository('AcmeDemoBundle:Person'); #entity repository 
$em = $this->getDoctine()->getEntityManager(); 

$person = $personRepository->find($id); 
$address = $person->getAddress(); 
$person->setAddress(NULL); 
$em->remove($address); 
$em->flush(); 

夫婦的旁註:

  • 必須調用這個,如果你有CASCADE約束外鍵。否則你會寬鬆Person記錄。
  • 如果將約束更改爲​​,則不需要$person->setAddress(NULL)行,因爲它會自動設置NULL值。

希望這有助於....

+0

這個工作正常,當我更新'setAddress()' - 方法也接受'null'值時。我第一次嘗試將* ORM *設置爲'nullable = true',但這不起作用。當有很多「鬆散」的關係時,這看起來像很多編碼工作。非常感謝。 – insertusernamehere

+0

因此,儘管事實上我們手中有PK,但我們還是需要2次去DB才能刪除這一行。一個填寫一個對象,以便我們可以將其刪除。爲什麼不直接使用ID發送刪除數據庫? –

+0

如果您有'SET NULL'FK約束(如第二個項目符號所指出的),您可以刪除'Person'。否則,你必須首先從'地址'中分離出'人'... –

1

jperovic解決方案的工作 - 我dind't測試,但它聽起來不錯。
我可以建議你的是,爲減少代碼和可能的誤差的大小,按照這個街道之一:

  1. ORM基於 - read more
  2. RDBMS基於 - 使用ON DELETE SET NULL直接進入外鍵到你的桌子,即

    CONSTRAINT fk_18ffff524ebd63f2 FOREIGN KEY (canale_id) 
        REFERENCES canale (id) MATCH SIMPLE 
        ON UPDATE NO ACTION ON DELETE CASCADE 
    

(和PostgreSQL)

+0

非常感謝您的回答。事情是,當使用cascade = {「remove」}時,這兩個對象都會被刪除。在這種情況下:不管哪一個被刪除,另一個應該停留。或者我忽略了什麼? – insertusernamehere

+0

@insertusernamehere是的,對不起。用「刪除」刪除所有相關的對象。我的錯。我的意思是「設置爲空」。我會更新;-) 編輯:剛剛更新:) – DonCallisto

+0

+ 1非常感謝您的更新。 – insertusernamehere

相關問題