修改父实体时删除子实体

时间:2012-04-12 11:16:20

标签: symfony doctrine-orm

我正在我的控制器中修改文件操作。子实体(StrOrigin)与文件实体具有以下关系:

/**
* @ORM\ManyToOne(targetEntity="File" )
* @ORM\JoinColumn(name="STOR_FILE", referencedColumnName="id", onDelete="CASCADE")
*/

现在在我在控制器中的修改操作中,我得到要修改的文件,设置表单并进行一些测试然后上传文件,保存文件实体并覆盖StrOrigin(这是文件中的许多字符串)和新修改的文件。我陷入了如何覆盖StrOrigin的困境。我在提交并保留新文件时尝试删除旧文件:

 $this_file_STROR=$em->getRepository('File')->find(array('id'=>$idfile));
                    $em->remove($this_file_STROR);
                    $em->flush();

但这似乎不起作用。

2 个答案:

答案 0 :(得分:0)

跟进评论:

您不想删除实际文件。你误解了onDelete="CASCADE"!这意味着当您删除文件时,所有StrOrigin也将被删除。它与你想要达到的目标无关。

您想要的是以下内容:

$this_file_STROR=$em->getRepository('File')->find($idfile);
foreach($this_file_STROR->getStrOrigins() AS $strOrigin){
  $em->remove($strOrigin);
}
// now $this_file_STROR as no StrOrigins anymore
$em->flush();

另请注意,此时您无需刷新。刷新只是将当前对象持久保存到数据库中。只要您使用对象,就不需要刷新。通常,您可以在脚本结束前立即刷新,例如在控制器中调用render之前。如果多次刷新,由于与数据库的交互,您的应用程序可能会很慢。

答案 1 :(得分:0)

我找到了另一种可能更快的解决方案:

它描述了here,被称为孤儿删除。我们的想法是简单地删除关联并告诉学说应该删除不再提及的相关实体。在您的情况下,您将执行以下操作:

/** 
* @ORM\ManyToOne(targetEntity="File" ) 
* @ORM\JoinColumn(name="STOR_FILE", referencedColumnName="id", orphanRemoval=true) 
*/

public function deleteStrOrigins(){
        $this->strOrigins = new ArrayCollection(); // you can also try to use = null. I'm using ArrayCollections, so this is my way and I never tried the null approach.
}

现在调用你的代码

$this_file_STROR=$em->getRepository('File')->find($idfile);
$this_file_STROR->deleteStrOrigins();
$em->flush();

应删除所有相关的StrOrigins,只要它们与其他任何地方无关。