0

我正在使用 Doctrine 2.1,其中支持通过外部实体的身份(外键作为标识符)。

http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/tutorials/composite-primary-keys.html#identity-through-foreign-entities

是否可以通过具有双向关系的外国实体进行身份识别?我正在尝试,但在加载数据设备时出现以下错误:

[PDO异常]

SQLSTATE [23000]:完整性约束违规:1452 无法添加或更新子行:外键约束失败(table. user, CONSTRAINT FK_187DDE86BF396750FOREIGN KEY ( id) REFERENCES address( user_id))

这是我的实体:

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

..但似乎我将不得不这样做:

$address = $entityManager->find('Address', $user->getId());

那正确吗?有没有办法做到这一点?

更新1:

我希望能够从任一侧(双向)设置关系,但这似乎不可能。

老实说,我不确定关系的反面的意义是什么,因为“仅对关联的反面所做的更改被忽略”

取自这里的文档:http: //docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/association-mapping.html#owning-side-and-inverse-side

重点是什么?

从应用程序的角度来看,这样做似乎更有意义:

$user->setAddress($address);

而不是:

$address->setUser($user);

但是第一个是不可能的,因为:

  1. 使关系双向刹车
  2. User一面必须是反面,所以无论如何$user->setAddress($address);都会被忽略!

请有人解释一下:)

马修

4

2 回答 2

1

您的问题与“作为标识符的外键”无关,而是与关系的拥有方有关:

在 Doctrine 中,关系可能是双向的,但在这种情况下,关系必须有一个“onwing-side”。这意味着:

  • 在您的“实体部分”:您的两个实体都有一个相互引用的属性。在您的情况下,您在用户中有 $address,在地址中有 $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 无法自动更新对方。所以你必须手动完成。由于每次创建新用户和地址时都不必考虑这一点,您可以在 setter 中自动执行该过程:

// 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);
于 2013-10-02T17:07:17.003 回答
0

您的用户实体中定义的地址字段是否有 getter?

public function getAddress()
{
  return $this->address;
}

请记住,学说总是返回集合。

于 2012-08-31T07:34:45.940 回答