我正在使用Doctrine 2.1,其中支持通过外国实体进行身份识别(外键作为标识符)。
是否可以通过双向关系通过外国实体进行身份识别?我正在尝试但是当我加载数据夹具时出现以下错误:
[PDOException]
SQLSTATE [23000]:完整性约束违规:1452无法添加或更新子行:外键约束失败(
table
。user
,CONSTRAINTFK_187DDE86BF396750
FOREIGN KEY({{ 1}})参考id
(address
))
以下是我的实体:
user_id
如果我从User删除引用,则错误消失!
我希望能够做到以下几点:
/**
* @Entity
*/
class User
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @OneToOne(targetEntity="Address") */
private $address;
}
/**
* @Entity
*/
class Address
{
/** @Id @OneToOne(targetEntity="User") */
private $user;
}
..但似乎我必须这样做:
$address = $user->getAddress();
是吗?有没有办法做到这一点?
更新1:
我希望能够从任何一方设置关系(双向),但这似乎不可能。
老实说,我不确定关系的反面是什么意思,因为“只会忽略关联的反面变化”。
有什么意义?
从应用程序的角度来看,似乎更有意义:
$address = $entityManager->find('Address', $user->getId());
而不是:
$user->setAddress($address);
然而,第一个是不可能的,因为:
$address->setUser($user);
方必须是反面,所以User
无论如何都会被忽略!! 请有人解释一下:)
马修
答案 0 :(得分:1)
您的问题与“外键作为标识符”无关,而是与关系的拥有方有关:
在Doctrine中,关系可能是双向的,但在这种情况下,关系必须具有“onwing-side”。这意味着:
:您的实体都具有相互引用的属性。在您的情况下,您在User中有$地址,在地址中有$ user,您可以使用$ user-> getAddress()和$ address-> getUser()
在“sql部分”上:只有一个表(拥有方)具有引用另一个表的属性。
您可以通过在非拥有方使用“mappedBy”来通知Doctrin拥有哪一方。 在您的情况下,使用外键作为标识符,您无法选择:拥有方是具有外键的方。 所以,测试一下:
/**
* @Entity
*/
class User
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @OneToOne(targetEntity="Address", mappedBy="user") */
private $address;
}
/**
* @Entity
*/
class Address
{
/** @Id @OneToOne(targetEntity="User", inversedBy="address")) */
private $user;
}
另一个重点: 在双向关系中,当您设置非拥有方时,Doctrine无法自动更新另一方。所以你必须手工制作。为了在每次创建新用户和地址时都没有考虑到这一点,您可以在设置器中自动执行该过程:
// in class User :
public function setAddress($address) {
$address->setUser($this); // <= here it is !!!
$this->address = $address;
return $this;
}
// in class Address :
public function setUser($user) {
$this->user = $user;
return $this;
}
现在,您可以设置您想要的地址,而无需担心这些拥有的东西:
$address = new Addresse();
$address->set...
$user->setAddress($address);
答案 1 :(得分:0)
您是否拥有用户实体中定义的地址栏的吸气剂?
public function getAddress()
{
return $this->address;
}
请记住,学说总是回归。