2

我有两个实体: aPerson和 an Address

  • 一个Person可以有一个Address
  • anAddress可以自给自足地生活Person

我已经创建了这样的关系:

地址

/**
 * @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时,它当然会导致“违反完整性约束”。我怎么能告诉教义简单地Address. Person如果尝试cascade={"detach"}在两者上使用但没有任何反应。

4

3 回答 3

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;

这个设置非常适合我。当您删除地址时,person 将在 address_id 中获得 NULL。如果您执行以下操作,Cascade all in Address 也将保存新人:

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

$person 将在哪里:

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

如果这不起作用,请从控制器或单元测试中发送代码。它应该只是最基本的代码;如果您使用地址,您只需保留地址实体。个人实体也是如此。你不需要坚持两者,教义会解决这个问题。

于 2012-11-15T16:01:32.773 回答
1

您可以像这样删除它:

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

  • 如果您有CASCADE外键约束,则必须调用它。否则你也会丢失 Person记录。
  • 如果您将约束更改SET NULL为线$person->setAddress(NULL),则不需要,因为它会自动设置该NULL值。

希望这可以帮助....

于 2012-11-15T12:16:21.493 回答
1

jperovic解决方案正在工作 - 我没有测试它,但对我来说听起来不错。
我可以向您建议的是,为了减少代码量和可能的错误,请遵循以下一条:

  1. 基于 ORM -阅读更多
  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)

于 2012-11-15T13:39:47.007 回答