Symfony 如何删除可以位于“中”的实体;“OneToMany”-关系

Symfony 如何删除可以位于“中”的实体;“OneToMany”-关系,symfony,doctrine,one-to-many,Symfony,Doctrine,One To Many,我有两个实体:一个人和一个地址 人可以有地址 地址可以从人那里自给自足地生活 我创造了这样的关系: $id = ...; #some id $personRepository = $this->getDoctrine()->getRepository('AcmeDemoBundle:Person'); #entity repository $em = $this->getDoctine()->getEntityManager(); $person = $person

我有两个实体:一个
和一个
地址

  • 可以有
    地址
  • 地址可以从
    人那里自给自足地生活
我创造了这样的关系:

$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();
地址

/**
*@ORM\OneToMany(targetEntity=“Person”,mappedBy=“address”,cascade={“detach”})
*/
受保护的人;

/**
*@ORM\ManyToOne(targetEntity=“Address”,inversedBy=“persons”,cascade={“detach”})
*@ORM\JoinColumn(name=“address\u id”,referencedColumnName=“id”)
*/
受保护的$地址;

当我现在尝试删除与
人相关的
地址
时,当然会导致“完整性约束冲突”。我如何告诉条令只需将
地址
分离。如果尝试在两个组件上都使用
cascade={“detach”}
,但没有任何结果。

您可以这样删除它:

$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();
关于
$person->setAddress(NULL)
的几个旁注:

  • 如果外键具有
    级联
    约束,则必须调用此函数。否则,您也将丢失
    个人
    记录
  • 如果将约束更改为
    SET NULL
    ,则不需要行
    $person->setAddress(NULL)
    ,因为它将自动设置
    NULL
希望这有帮助……

解决方案正在运行-我还没有测试过,但听起来不错
为了减少代码量和可能出现的错误,我可以向您建议如下:

  • 基于ORM的-
  • 基于RDBMS-在删除时使用
    将NULL设置为外键,直接输入到表中,即

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

    人:

    /**
    * @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;
    
    这个设置非常适合我。当您删除地址时,地址\ id中的人员将为空。如果您执行以下操作,则级联所有in地址也将保存新人员:

    $address->setPersons(
        array( $person1, $person2 )
    ) ;
    
    如果$person为:

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

    如果这不起作用,请从控制器或单元测试发送代码。它应该是最基本的代码;如果使用地址,则只需持久化地址实体。个人和实体也一样。您不需要同时坚持这两种操作,条令将解决这一问题。

    detach
    delete
    操作之间存在差异(显然)。我假设您想从数据库中物理删除记录,对吗?实际上我想物理删除
    地址
    ,并重置
    个人
    中的引用。好的,我添加了适合您的问题的答案…当我更新
    setAddress()时,这个答案很好用
    -也接受
    null
    -值的方法。我首先尝试将ORM设置为
    nullable=true
    ,但没有成功。当有很多“松散”的关系时,这似乎需要大量的编码工作。非常感谢。因此,尽管我们手中有行的主键,我们还是要到DB去删除行。一个用来填充一个对象,这样我们就可以在删除它时掉头。为什么不直接用ID对数据库进行删除?如果您有
    设置NULL
    FK约束(如第二个项目符号中所指出的),您可以直接删除
    Person
    。否则,您必须首先将
    人员
    地址
    分离……非常感谢您的回答。问题是,当使用
    cascade={“remove”}
    时,两个对象都会被删除。在这种情况下:无论删除哪一个,另一个都应该保留。还是我忽略了什么?@InsertUserName这里是的,对不起。。使用“移除”将移除所有相关对象。是我的错。我的意思是“设为空”。我将更新;-)编辑:刚刚更新:)这将是一个非常简单的解决方案。:)当我用你的代码更新我的代码时,当我删除
    地址
    时,
    也会被删除。Argh.通过删除
    cascade={“all”}
    或放置
    cascade={“persist”}
    来尝试。您的控制器代码是什么,可能您在那里有一些错误?这再次带来了良好的旧违规。:)我已经用
    地址的删除操作更新了这个问题
    cascade={“all”}
    必须删除,代码才能工作。非常令人印象深刻-它可以工作。它是如此光滑。令人惊叹的。非常感谢你的耐心。这有点尴尬:在添加了
    onDelete
    -语句之后,我忘记了更新数据库。