2017-03-23 29 views
1

我有以下代碼:爲什麼我需要刪除(後刷新()),堅持()之前,在教義

//Delete old existing file(s) 
$files = $record->getFiles(); 

foreach ($files as $file) { 
    $em->remove($file); 
} 

$em->flush(); 

$link = $record->getLink() ? $record->getLink() : new Link(); 
$link->setRecord($record); 
$link->setUrl($metaData['location']); 

$em->persist($link); 

$em->flush(); 

我需要調用第一flush()否則$file實體不會被刪除..爲什麼他們不會被第二個flush()刪除?

僅供參考,這裏是Record的關係定義:

/** 
* @var \AppBundle\Entity\Link 
* 
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Link", cascade={"persist"}, mappedBy="record") 
*/ 
private $link; 

/** 
* @var \AppBundle\Entity\File 
* 
* @ORM\OneToMany(targetEntity="AppBundle\Entity\File", cascade={"persist"}, mappedBy="record") 
*/ 
private $files; 

此外,該代碼使用單一的flush()工作正常(它刪除,而不是一對多一個OneOnOne實體):

//Delete old existing link 
$link = $record->getLink(); 
if ($link) { 
     $em->remove($link); 
} 

$file = $record->getFile() ? $record->getFile() : new File(); 
$file->setRecord($record); 

$em->persist($file); 

$em->flush(); 
+0

'$ files'屬性上'orphanRemoval = true'怎麼辦? 然後你有一個文件'集合',你可以重置,如果需要'記錄'實體刷新 – ceadreak

+0

孤兒不起作用,問題在於'cascade = {「persist」}'文件。我會做更多的調試,看看我能否弄清楚 – Oli

回答

1

我發現讓我的代碼工作的兩種方式,它採取兩種不同的方法:

第一種情況:不要設置任何級聯邏輯實體並手動處理所有操作。

記錄實體

/** 
* @var \AppBundle\Entity\Link 
* 
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Link", mappedBy="record") 
*/ 
private $link; 

/** 
* @var \AppBundle\Entity\File 
* 
* ORM\OneToMany(targetEntity="AppBundle\Entity\File", mappedBy="record") 
*/ 
private $files; 

控制器

//Delete old existing file(s) 
$files = $record->getFiles(); 

foreach ($files as $file) { 
    $fileService->deleteFile($file); 
    //Remove the *owning* entity of the relationship 
    $em->remove($file); 
} 

$em->flush(); 
$em->clear(); 

//We need to call clear() to remove all existing references of files 
//from the $record entity. Get the record again after this. 
$record = $this->getRecordRepository()->findActive($id); 

$link = $record->getLink() ? $record->getLink() : new Link(); 
$link->setRecord($record); 
$link->setUrl($metaData['location']); 

$em->persist($link); 
$record->setType(Record::TYPE_LINK); 

$em->flush(); 

第二種情況:從$record角度來處理所有的數據庫操作,並讓cascadeorphanRemoval做休息

記錄實體

/** 
* @var \AppBundle\Entity\Link 
* 
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Link", cascade={"persist", "remove"}, mappedBy="record", orphanRemoval=true) 
*/ 
private $link; 

/** 
* @var \AppBundle\Entity\File 
* 
* @ORM\OneToMany(targetEntity="AppBundle\Entity\File", cascade={"persist", "remove"}, mappedBy="record", orphanRemoval=true) 
*/ 
private $files; 

控制器

//Delete old existing file(s) 
$files = $record->getFiles(); 

foreach ($files as $file) { 
    $fileService->deleteFile($file); 
    $record->removeFile($file); 
} 

$link = $record->getLink() ? $record->getLink() : new Link(); 
$link->setRecord($record); 
$link->setUrl($metaData['location']); 

$em->persist($link); 
$record->setType(Record::TYPE_LINK); 

$em->flush(); 

我個人偏愛的第二種方法,它需要較少的PHP代碼是更具有可讀性。

我會離開這個答案任何意見/提示打開並關閉它本週。

0

cascade參數有一個選項:'remove','persist','refresh','merge'和'detach'。

把他們當作標誌,所以你可以這樣寫:

cascade={"persist","remove"} 

甚至:

cascade={"all"} 

也許這有助於...

相關問題