symfony バンドルの Resources/config/doctrine フォルダーに yml-syntax を使用してエンティティを作成しました。
Sulu\Bundle\TranslateBundle\Entity\Translation:
type: entity
table: tr_translations
id:
code:
type: string
column: idCodes
associationKey: id
catalogue:
type: string
column: idCatalogues
associationKey: id
fields:
value:
type: text
manyToOne:
code:
targetEntity: Code
inversedBy: tr_codes
joinColumn:
name: idCodes
referencedColumnName: id
catalogue:
targetEntity: Catalogue
inversedBy: tr_catalogues
joinColumn:
name: idCatalogues
referencedColumnName: id
この部分は正常に動作しています。しかし、次のコードのようなオブジェクトを作成すると、外部キーの ID を取得するために、flush メソッドを使用する必要があるというエラー メッセージが表示されます。
これは、私が現在使用しているコード スニペットです。
// create a new package and catalogue for the import
$package = new Package();
$package->setName($this->getName());
$catalogue = new Catalogue();
$catalogue->setLocale($this->getLocale());
$catalogue->setPackage($package);
$this->em->persist($package);
$this->em->persist($catalogue);
// load the file, and create a new code/translation combination for every message
$fileCatalogue = $loader->load($this->getFile(), $this->getLocale());
foreach ($fileCatalogue->all()['messages'] as $key => $message) {
$code = new Code();
$code->setPackage($package);
$code->setCode($key);
$code->setBackend(true);
$code->setFrontend(true);
$translate = new Translation();
$translate->setCode($code);
$translate->setValue($message);
$translate->setCatalogue($catalogue);
$this->em->persist($code);
$this->em->flush(); //FIXME no flush in between, if possible
$this->em->persist($translate);
}
// save all the changes to the database
$this->em->flush();
foreach ループでフラッシュを呼び出さないと、次のエラーが表示されますが、これは完全に理解できますが、この問題に対するより洗練された解決策はありませんか?
Doctrine\ORM\ORMException : タイプ Sulu\Bundle\TranslateBundle\Entity\Translation のエンティティは、外部エンティティ Sulu\Bundle\TranslateBundle\Entity\Code を介して ID を持っていますが、このエンティティ自体には ID がありません。関連するエンティティで EntityManager#persist() を呼び出し、「Sulu\Bundle\TranslateBundle\Entity\Translation」を永続化する前に識別子が生成されていることを確認する必要があります。Post Insert ID Generation (MySQL Auto-Increment や PostgreSQL SERIAL など) の場合、これは両方の永続操作の間に EntityManager#flush() を呼び出す必要があることを意味します。