2017-03-23 28 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"} 

也许这有助于...

相关问题