Symfony Fixtures关联数据报Reference already exists错误如何解决
问题根源
你触发报错的原因是 addReference() 方法要求每个引用的标识全局唯一,你在创建5个分类的循环中,每次都用同一个genre_reference作为标识注册引用,第二次循环时系统检测到标识已存在就抛出了报错。
setReference 与 addReference 的区别
addReference():用于新增引用,若指定标识已存在直接抛出报错,适合新增唯一标识的场景setReference():用于设置引用,若指定标识已存在会直接覆盖原有值不会报错,适合需要更新已有引用的场景
解决方案
你的场景是要创建多个分类并给图书随机关联,不需要使用setReference,只要给每个分类的引用标识加上唯一序号即可:
- 修改 GenreFixtures 代码,给引用标识增加序号后缀
class GenreFixtures extends Fixture { public function load(ObjectManager $manager): void { $faker = Factory::create('fr_FR'); $faker->seed(123); for ($i=0; $i < 5; $i++) { $genre = new Genre(); $genre->setName($faker->colorName); $manager->persist($genre); // 追加序号保证每个引用标识唯一 $this->addReference('genre_reference_' . $i, $genre); } $manager->flush(); } }
- 修改 LivreFixtures 代码,随机读取不同的分类引用关联到图书
class LivreFixtures extends Fixture implements DependentFixtureInterface { public function load(ObjectManager $manager): void { $faker = Factory::create('fr_FR'); $faker->seed(123); for ($i = 0; $i < 10; $i++) { $livre = new Livre(); $livre->setTitre($faker->sentence($nbWords = 4, $variableNbWords = true)); $livre->setAuteur($faker->name); $livre->setDescription($faker->text); $livre->setDateDeParution($faker->dateTime($format = 'Y-m-d')); // 随机取0-4的序号,关联对应分类 $livre->setGenre($this->getReference('genre_reference_' . random_int(0, 4))); $manager->persist($livre); } $manager->flush(); } public function getDependencies() { return array( GenreFixtures::class, ); } }
如果你希望所有图书都关联同一个分类,也可以直接把 GenreFixtures 中的addReference改为setReference,循环结束后genre_reference标识会指向最后一个创建的分类,无需修改LivreFixtures的代码即可正常运行。
内容的提问来源于stack exchange,提问作者Lia Ah
相关产品推荐
相关产品推荐

