将OneToMany关联改为ManyToMany时出现Id未找到问题求助
解决Symfony中Devis与Dossier的ManyToMany关联配置问题
问题核心是Doctrine默认假设实体主键为id,但你的表主键是自定义的id_devis和id_dossier,必须在关联注解中明确指定主键映射关系。以下是正确的实体配置步骤:
1. 修正Devis实体的关联配置
Devis作为关联的被动端(mappedBy),只需指定关联目标和映射源:
// src/Entity/Devis.php namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'devis')] class Devis { #[ORM\Id] #[ORM\Column(name: 'id_devis', type: 'integer')] #[ORM\GeneratedValue(strategy: 'IDENTITY')] private ?int $id = null; #[ORM\ManyToMany(targetEntity: Dossier::class, mappedBy: 'devis')] private Collection $dossiers; public function __construct() { $this->dossiers = new ArrayCollection(); } // 基础getter/setter public function getId(): ?int { return $this->id; } public function getDossiers(): Collection { return $this->dossiers; } }
2. 修正Dossier实体的关联配置
Dossier作为关联的主控端,必须通过@JoinTable明确配置中间表的外键与实体主键的对应关系:
// src/Entity/Dossier.php namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ORM\Table(name: 'dossier')] class Dossier { #[ORM\Id] #[ORM\Column(name: 'id_dossier', type: 'integer')] #[ORM\GeneratedValue(strategy: 'IDENTITY')] private ?int $id = null; #[ORM\ManyToMany(targetEntity: Devis::class, inversedBy: 'dossiers')] #[ORM\JoinTable( name: 'devis_dossier', joinColumns: [ #[ORM\JoinColumn(name: 'id_dossier', referencedColumnName: 'id_dossier')] ], inverseJoinColumns: [ #[ORM\JoinColumn(name: 'id_devis', referencedColumnName: 'id_devis')] ] )] private Collection $devis; public function __construct() { $this->devis = new ArrayCollection(); } // 基础getter/setter public function getId(): ?int { return $this->id; } public function getDevis(): Collection { return $this->devis; } }
3. 生成并执行正确的迁移
- 删除之前生成的错误迁移文件(若已存在)
- 运行命令生成迁移:
php bin/console make:migration
此时生成的SQL会正确关联外键:
ALTER TABLE devis_dossier ADD CONSTRAINT FK_AFA67B6BE3D54947 FOREIGN KEY (id_dossier) REFERENCES dossier (id_dossier); ALTER TABLE devis_dossier ADD CONSTRAINT FK_AFA67B6B65A2841B FOREIGN KEY (id_devis) REFERENCES devis (id_devis);
- 执行迁移更新数据库:
php bin/console doctrine:migrations:migrate
额外注意
- 若之前OneToMany关联在
dossier表中遗留了id_devis字段,迁移会自动生成该字段的删除语句,确认后执行即可。 - 中间表名
devis_dossier为Doctrine默认生成规则,若需要自定义,直接修改@JoinTable的name属性即可。
内容的提问来源于stack exchange,提问作者CE_
相关产品推荐
相关产品推荐

