Zend2 Doctrine2 One-To-Many单向连接表,删除级联问题

时间:2013-04-04 17:10:27

标签: doctrine-orm zend-framework2 cascade one-to-many joincolumn

我遇到以下问题...... 我有一张电话号码表。我想为用户和公司使用相同的表。用户可以拥有多个电话号码和一个公司。所以我希望与两个不同的连接表具有一对多的单向关系。一个将电话号码链接到用户,另一个将电话号码链接到公司。 这是遵循doctrine2手册第5.9章中的解决方案:(click)

我的用户实体持有此代码:

/** @ORM\ManyToMany(targetEntity="Application\Entity\PhoneNumber")
  * @ORM\JoinTable(name="user_phone_number_linker",
  *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
  *      inverseJoinColumns={@ORM\JoinColumn(name="phone_number_id", referencedColumnName="id")}
  *      )
  */
  protected $phone_numbers;

我使用单向一对多,因为事情是我不能制作双向的,因为如果我回头告诉用户我不能为公司使用相同的电话号码实体类。现在一切正常,但当我删除电话号码时,我收到以下错误: 执行'DELETE FROM phone_number WHERE id =?'时发生异常用params {“1”:1}:

SQLSTATE [23000]:完整性约束违规:1451无法删除或更新父行:外键约束失败(database/user_phone_number_linker,CONSTRAINT user_phone_number_linker_ibfk_11 FOREIGN KEY(phone_number_id)REFERENCES { {1}}(phone_number))

如果我在数据库中手动设置ON DELETE CASCADE值,它工作正常,但这不是使用doctrine2的想法,我想我应该能够在代码中解决它,而无需进入我的phpMyAdmin面板。不知何故,从电话号码到连接表的级联应该在删除时启动,但不能从phone_number实体返回连接表。

希望聪明的人可以帮我解决这个问题。

修改

与此同时,我学到了很多关于Doctrine2的知识,并且回顾我的旧问题让我意识到这不是一个正确的方法,可以将几个phoneNumber存储在一个表中。为了能够在同一个表中存储用户电话号码和公司电话号码,我应该使用带有鉴别器列的表继承。该列应该包含一些用户/公司鉴别器。

由于此专栏,学说ORM将“知道”该phoneNumber实际上是用户还是公司电话号码。我需要在the single table inheritance mapping principles from the doctrine 2 specs之后制作两个不同的实体定义。

一个班级idUserPhoneNumber建立many-to-one关系,另一个班级UserCompanyPhoneNumber建立one-to-many关系。我不一定需要加入列,Companyuser_id列可以在电话号码表中。在company_id类中省略了User关联,在Company类中省略了Company关联(数据库应该允许这些列的空值)。

如果我使用连接表,则根据one-to-many unidirectional with join table description in the Doctrine2 specs

阅读更多

否则,您还可以在this elaborate Doctrine2 in depth website上阅读有关关联和级联问题的更多信息。

2 个答案:

答案 0 :(得分:1)

正如你所说,你的关系是单向的。您已经定义了从Users到PhoneNumbers的关系。删除用户时,级联删除将起作用,它将删除user_phone_number_linker中的所有行,因为这是您定义的关系。

如果您想以另一种方式执行此操作,则必须创建从PhoneNumbers到Users的关系。学说需要它为你工作。但是您遇到的问题是该实体由另外两个实体Users和Companies共享。

请记住,实体是对象,而不是表。因此,您可以尝试在同一个表中创建两个实体,一个名为PhoneNumberUsers,另一个名为PhoneNumberCompanies。这样,您就可以创建所需的关系来执行级联删除。我没有亲自测试,但我认为它可以工作。

顺便说一下,您可以删除用户实体连接表上的oncascade参数。我与用户和角色的情况相同,我没有使用它。我认为只有当你想从实体级联到实体时才需要它。我不确定,但这就是我到目前为止所经历的。

答案 1 :(得分:0)

我的坏, 电话号码用户关系被视为多对多关系,因此如果想要移除电话号码,我不仅应该删除电话号码本身,而且还必须明确删除用户的电话号码。所以在控制器中这样:

// Remove the phone number user connection from the database
$user->removePhoneNumber($phone_number);

// Remove the phone number from the database
$em->remove($phone_number);

我只是认为与单向一对多关系的独特限制足以让学说处理它。那不对。