【发布时间】:2014-04-22 13:00:22
【问题描述】:
我有一个Person 实体和一个Address 实体,设置为双向一对一关系,FK 位于Address:
...
class Person
{
...
/**
* @ORM\OneToOne(targetEntity="Address", mappedBy="person")
*/
protected $address;
...
}
...
class Address
{
...
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="Person", inversedBy="address")
* @ORM\JoinColumn(name="personID", referencedColumnName="id")
*/
protected $person;
}
Address 实体没有专用的主键,而是通过与Person 的外键关系派生其身份,如explained here
我用于创建新人员的表单也嵌入了地址表单。提交表单时,会执行此控制器操作:
public function createAction(Request $request)
{
$person = new Person();
$form = $this->createCreateForm($person);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($person);
$em->flush();
return $this->redirect($this->generateUrl('people'));
}
return array(
'person' => $person,
'form' => $form->createView(),
);
}
我检查了数据,$person 的$address 属性按预期填写了正确的表单详细信息。但是,一旦 $person 对象被持久化,我就会收到错误消息:
通过关系发现了一个新实体 'Acme\AcmeBundle\Entity\Person#address' 未配置为 实体的级联持久化操作...
我已经尝试了几件事,但似乎都没有工作:
- 在 Person 对象的 OneToOne 关系定义上设置
cascade={"persist"}。这样做会导致错误:Acme\AcmeBundle\Entity\Address 类型的实体缺少分配的 字段“人”的 ID...
- 在
Person#setAddress方法上,我采用了$address参数并在其上手动调用$address->setPerson($this)。也不行。
Person 对象之前尝试保存 Address 对象,但它不能,因为它首先需要知道关联 Person 的 ID。
例如,如果我将持久代码更改为这样的内容,它可以工作:
...
// Pull out the address data and remove it from the Person object
$address = $person->getAddress();
$person->setAddress(null);
// Save the person object and flush so we get an ID
$em->persist($person);
$em->flush();
// Now set the person object on the address and save the address
$address->setPerson($person);
$em->persist($address);
$em->flush();
...
我怎样才能正确地做到这一点?我想保留使用这种一对一关系嵌入表单的能力,但事情开始变得复杂。如何让 Doctrine 在刷新 $address 对象之前刷新 $person 对象,而不像上面那样自己手动执行?
【问题讨论】:
标签: symfony doctrine-orm