2012-11-15 79 views
2

我有两个实体:一个Person和一个Address如何删除可能处于“OneToMany”关系的实体

  • 一个Person可以有一个Address
  • Address可以从Person生活自给自足。

I'have创建这样的关系:

地址

/** 
* @ORM\OneToMany(targetEntity="Person", mappedBy="address", cascade={"detach"}) 
*/ 
protected $persons; 

/** 
* @ORM\ManyToOne(targetEntity="Address", inversedBy="persons", cascade={"detach"}) 
* @ORM\JoinColumn(name="address_id", referencedColumnName="id") 
*/ 
protected $address; 

当我现在尝试删除Address是相关到Person它的结果,当然,在“完整性约束冲突”。我怎样才能告诉学说detachPerson。如果在两者上尝试使用cascade={"detach"}但没有任何反应。

+0

'detach'和'delete'操作(显然)有区别。我假设你想从数据库中物理删除记录,对吧? –

+0

其实我想删除物理地址,重置'Person'中的引用。 – insertusernamehere

+0

好的,我添加了应该适合您的问题的答案... –

回答

5

人:

/** 
* @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; 

这种设置完全适用于我。当你删除地址时,人将在address_id中得到NULL。级联全部地址也将保存新的人,如果你这样做:

$address->setPersons(
    array($person1, $person2) 
) ; 

其中$的人将是:

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

在这种情况下不能正常工作,请从控制器或发送代码单元测试。它应该只是最基本的代码;如果你使用地址,你只需坚持地址实体。同一个人实体。你不需要坚持这两个,教条将照顾到这一点。

+0

这将是一个非常简单的解决方案。 :)当我用你的代码更新我的代码时,碰巧当我删除一个Address时,Person也被删除了。哎呀。 – insertusernamehere

+1

尝试删除cascade = {“all”}或放置cascade = {“persist”}。你的控制器代码是什么,也许你在那里有一些错误? – Zeljko

+0

这会再次引发良好的旧*违规*。 :)我已通过删除“地址”动作更新了问题。 – insertusernamehere

1

可以删除它是这样的:关于$person->setAddress(NULL)

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

夫妇的旁注:

  • 必须调用这个,如果你有CASCADE约束外键。否则你会宽松Person记录。
  • 如果将约束更改为​​,则不需要$person->setAddress(NULL)行,因为它会自动设置NULL值。

希望这有助于....

+0

这个工作正常,当我更新'setAddress()' - 方法也接受'null'值时。我第一次尝试将* ORM *设置为'nullable = true',但这不起作用。当有很多“松散”的关系时,这看起来像很多编码工作。非常感谢。 – insertusernamehere

+0

因此,尽管事实上我们手中有PK,但我们还是需要2次去DB才能删除这一行。一个填写一个对象,以便我们可以将其删除。为什么不直接使用ID发送删除数据库? –

+0

如果您有'SET NULL'FK约束(如第二个项目符号所指出的),您可以删除'Person'。否则,你必须首先从'地址'中分离出'人'... –

1

jperovic解决方案的工作 - 我dind't测试,但它听起来不错。
我可以建议你的是,为减少代码和可能的误差的大小,按照这个街道之一:

  1. ORM基于 - read more
  2. RDBMS基于 - 使用ON DELETE SET NULL直接进入外键到你的桌子,即

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

(和PostgreSQL)

+0

非常感谢您的回答。事情是,当使用cascade = {“remove”}时,这两个对象都会被删除。在这种情况下:不管哪一个被删除,另一个应该停留。或者我忽略了什么? – insertusernamehere

+0

@insertusernamehere是的,对不起。用“删除”删除所有相关的对象。我的错。我的意思是“设置为空”。我会更新;-) 编辑:刚刚更新:) – DonCallisto

+0

+ 1非常感谢您的更新。 – insertusernamehere

相关问题