共享主键的两个表上的一对一关系 [英] One to one relationship on two tables sharing primary key
问题描述
我希望两个表 Person
和 Address
共享其主键:
I want two tables, Person
and Address
, to share their primary key:
CREATE TABLE Person (id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE Address (personId INT UNSIGNED NOT NULL PRIMARY KEY);
我正在尝试对创建 Person
,您还为此创建了地址
。
I'm trying to model the idea that when you create a Person
, you're also creating an Address
for it.
我想出了以下映射:
class Person
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;
/**
* @OneToOne(targetEntity="Address", cascade={"all"})
* @JoinColumn(name="id", referencedColumnName="personId")
*/
private $address;
public function __construct() {
$this->address = new Address($this);
}
}
class Address
{
/**
* @Id
* @OneToOne(targetEntity="Person")
* @JoinColumn(name="personId", referencedColumnName="id")
*/
private $person;
public function __construct(Person $person) {
$this->person = $person;
}
}
当我尝试坚持时人
,我希望它会级联到地址
,但出现以下异常:
When I try to persist Person
, I would expect it to cascade to Address
, but I get the following exception:
Doctrine\ORM\ORMException
Address类型的实体
通过外国实体Person
具有身份,
但是该实体本身没有身份。您必须在相关实体上调用
EntityManager#persist()
并确保在尝试持久保存<$ c $之前已生成
标识符c>地址。
用于生成后插入ID(例如MySQL自动递增
或PostgreSQLSERIAL
),这意味着您必须在两个持久操作之间调用EntityManager#flush()
。
Entity of type
Address
has identity through a foreign entityPerson
, however this entity has no identity itself. You have to callEntityManager#persist()
on the related entity and make sure that an identifier was generated before trying to persistAddress
. In case of Post Insert ID Generation (such as MySQLAuto-Increment
or PostgreSQLSERIAL
) this means you have to callEntityManager#flush()
between both persist operations.
我不能显式调用 flush()
,因为我没有显式调用 persist()
ing Address
,相反,我期望 Person
可以级联持久保存 Address
。
I can't explicitly call flush()
, because I'm not explicitly persist()
ing Address
, instead I'm expecting Person
to cascade persist Address
.
据我了解,Doctrine的工作是 flush()
在适当的时候获得 id
。
So as far as I understand it, it should be Doctrine's job to flush()
at the right moment to get the id
.
这种一对一的关系在使用不同的关系时可以很好地层叠 Address
的 auto_increment
id(但后来我必须向人员
添加 addressId
)。
This one-to-one relationship cascades fine when using different auto_increment
ids for both Person
and Address
(but then I have to add an addressId
to Person
).
我的目的是使他们共享相同的 id
。
My aim is to make them share the same id
.
有可能吗?
推荐答案
在您的方案中,您可以使用 @ManyToOne
代替 @OneToOne
关联。
In your scenario you can use @ManyToOne
instead @OneToOne
association.
当您保留拥有方时,关联将保留。在您的映射中,这是地址
。更改您的映射,以便所有者具有外键,并且一切正常。
The association is persisted when you persist the owning side. In your mapping, that is the Address
. Change your mapping so the owner has the foreign key and everything should work fine.
/**
* @OneToOne(targetEntity="Address", cascade={"all"}, inversedBy="person")
* @JoinColumn(name="id", referencedColumnName="personId")
*/
private $address;
换句话说,如果 Address
应该是人员
,那么您必须将地址
保留在第一位,以便保留关联。
如果您希望关联与 Person
保持一致,则应将 Person
标记为拥有方和地址
为反方:
In other words, if Address
should be owner by the Person
then you must persist Address
at first place to in order to persist the association.
If you want the association to be persisted with Person
, then you should mark the Person
to be the owning side and Address
to be the inverse side:
/**
* @Id
* @OneToOne(targetEntity="Person", inversedBy="address")
* @JoinColumn(name="personId", referencedColumnName="id")
*/
private $person;
这篇关于共享主键的两个表上的一对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!