我必须先确定我是一个总的初来乍到的教义,尽管我有足够的了解SQL和PHP/Symfony的2学说2.2/2.2的Symfony:坚持实体与复合外键
所以,我创建关联到一个SQL表这个问题类型的实体:
/**
* IssueType
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Blog\Bundle\CoreBundle\Entity\IssueTypeRepository")
*/
class IssueType
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
// Getters, setters...
}
我填充它,这样的内容说,现在的表是:
id | name
1 | Bande dessinée
2 | Livre
3 | Film
4 | Disque
现在我有这个其他实体,角色,它使用复合键,由一个普通的字符串(名称)和外键(ID从问题类型)的:
/**
* Role
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Blog\Bundle\CoreBundle\Entity\RoleRepository")
*/
class Role
{
/**
* @var IssueType
*
* @ORM\ManyToOne(targetEntity="Blog\Bundle\CoreBundle\Entity\IssueType")
* @ORM\JoinColumn(nullable=false)
* @ORM\Id
*/
private $issueType;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
* @ORM\JoinColumn(nullable=false)
* @ORM\Id
*/
private $name;
// Getters, setters...
}
两个表是通过数据库中的教义正确生成。然而,尽管这应该是微不足道的,但我不能在我的生活中找到一个在这种情况下正确和成功坚持运作的例子。
我尝试做的是以下几点:
$manager = $this->getDoctrine()->getManager();
$issueType = new IssueType();
$issueType->setId(1);
$role = new Role();
$role->setIssueType($issueType);
$role->setName('Dessinateur');
$manager->persist($role);
$manager->flush();
我这样尝试坚持以下几点:
Role: {
IssueType: {id: 1, name: ''},
name: 'Dessinateur',
}
而我得到的是这个讨厌的例外:
Entity of type Blog\Bundle\CoreBundle\Entity\Role has identity through a foreign entity Blog\Bundle\CoreBundle\Entity\IssueType, however this entity has no identity itself. You have to call EntityManager#persist() on the related entity and make sure that an identifier was generated before trying to persist 'Blog\Bundle\CoreBundle\Entity\Role'. In case of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call EntityManager#flush() between both persist operations.
我明白它要我坚持第一个外国实体,但我不想这样做,因为外国问题类型ID#1已经存在于数据库中,因此不需要持久化。当我没有在注释中指定任何'级联'属性时,它怎么能问我?
BTY我试过,因为它说,它预计结束与重复的输入错误。
那么,我该怎么做才能使学说理解外国问题类型不应该被持续?
编辑
artmees提出了以下解决方案,工作正常:
$manager = $this->getDoctrine()->getManager();
$issueType = $manager->getRepository('BlogCoreBundle:IssueType')->find(1);
$role = new Role();
$role->setIssueType($issueType);
$role->setName('Dessinateur');
$manager->persist($role);
$manager->flush();
然而,这意味着提高到能够在不使用原则就可以避免数据库的额外请求。由于我已经知道要使用的外部标识,是否有任何方法可以直接使用persist(),而不需要像从数据库中实际检索完整对象那样的长度?
据我所知(限定任何可能的公牛)。当你调用' - > find(1)'时,懒惰加载对象而不是完全加载它。当你将它传递给'Role()'对象时,它从对象的代理版本中获得它所需的东西,在这方面它将是id(而不是整个对象)。 创建对象后,您需要调用persist(将对象排成数据库),然后刷新以将队列推送到数据库。正确使用它可以确保您将正确的对象而不是新鲜的对象与随机的,可能不正确的ID连接起来。 – qooplmao