SQL と PHP/Symfony 2 については十分に知っていますが、Doctrine の初心者であることを最初に確認する必要があります。
そこで、SQL テーブルに関連付けられた次の IssueType エンティティを作成しました。
/**
* 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
これで、通常の文字列 (名前) と外部キー (IssueType の ID) で構成される複合キーを使用する別のエンティティ、Role ができました。
/**
* 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...
}
両方のテーブルは、データベースの教義によって正しく生成されます。ただし、それは些細なことのはずですが、私の人生では、そのような場合に正しく成功した持続操作の例を1つも見つけることができません。
私がやろうとしていることは次のとおりです。
$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とにかく言われたとおりにしようとしましたが、重複エントリエラーが発生することが予想されました。
では、Doctrine に外国の課題タイプを永続化してはならないことを理解させるにはどうすればよいでしょうか?
編集
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();
ただし、これは、Doctrine を使用していなければ回避できたデータベースへの追加のリクエストを行うことを意味します。使用する外部 ID を既に知っているので、データベースから完全なオブジェクトを実際に取得するような長さを使わずに、persist() で直接使用する方法はありますか?