我有以下代码:
//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实体而不是OneToMany):
//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 :(得分: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
角度处理所有数据库操作,让cascade
和orphanRemoval
完成剩下的工作记录实体
/**
* @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代码更具可读性。
我会在任何评论/提示中留下这个答案,并在本周结束。
答案 1 :(得分:0)
cascade
参数有一个选项:&#39;删除&#39;,&#39;坚持&#39;,&#39;刷新&#39;&#39;合并&#39;,和&#39;分离&#39;。
将它们视为标志,以便您可以写:
cascade={"persist","remove"}
甚至:
cascade={"all"}
也许这有帮助...