我有两个实体 - TestUser
和TestAddress
。 Address与User具有OneToOne关系,它的主键也是User的外键。
/**
* @ORM\Entity
*/
class TestUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
private $id;
}
/**
* @ORM\Entity
*/
class TestAddress
{
/**
* @ORM\Id
* @ORM\OneToOne(targetEntity="TestUser")
*/
private $user;
/**
* @param $user
*/
public function setUser($user)
{
$this->user = $user;
}
}
当我尝试通过entityManager保存两个实体时,我得到一个例外。
$em = $this->getEntityManager();
$user = new TestUser();
$address = new TestAddress();
$address->setUser($user);
$em->persist($user);
$em->persist($address);
$em->flush();
例外:
Doctrine\ORM\ORMInvalidArgumentException: The given entity of type 'Entity\TestAddress' (Entity\TestAddress@000000004fcda1bf000000002f07b49b) has no identity/no id values set. It cannot be added to the identity map.
只保存两个实体的方法是“刷新”用户,然后保持并刷新地址。
$em->persist($user);
$em->flush();
$em->persist($address);
$em->flush();
问题:有没有办法在TestUser id上使用自动增量并使用一次刷新保存TestUser和TestAddress实体?
答案 0 :(得分:0)
class TestAddress
{
/**
* @ORM\OneToOne(targetEntity="TestUser", cascade={"persist"})
*/
private $user;
答案 1 :(得分:0)
我知道它甚至不是你问题的答案,但IMO你应该重新考虑这个模式选择的目的,当地址实体的ID必须对应于用户实体的ID。我不认为这是必要的,你可以通过在Address实体上使用单独的外键和主键字段来改善。
然而,您可以尝试的另一件事是使关系成双向,即在User对象上定义testAddress变量,然后向其添加相应的映射信息:
/**
* @OneToOne(targetEntity="TestAddress", mappedBy="user", cascade={"persist"})
*/
private $testAddress;
然后您可能还需要在用户实体上创建setTestAddress()方法,并在那里显式设置TestAddress的用户对象:
public function setTestAddress($address)
{
$address->setUser($this);
$this->testAddress = $address;
}
然后您可以调用$ user-> setTestAddress($ address)并尝试仅刷新用户实体:
$user = new TestUser();
$address = new TestAddress();
$user->setTestAddress($address);
$em->persist($user);
$em->flush();
我不太熟悉doctrine持久化实体的顺序,但是让实体被TestUser实体持久化而不是相反(如建议的那样)用户应首先保留,而不是将其ID添加到它之前的地址甚至是持久的。
我没有测试代码,所以可能会有一些错误。