You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将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. 生成并执行正确的迁移

  1. 删除之前生成的错误迁移文件(若已存在)
  2. 运行命令生成迁移:
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);
  1. 执行迁移更新数据库:
php bin/console doctrine:migrations:migrate

额外注意

  • 若之前OneToMany关联在dossier表中遗留了id_devis字段,迁移会自动生成该字段的删除语句,确认后执行即可。
  • 中间表名devis_dossier为Doctrine默认生成规则,若需要自定义,直接修改@JoinTable的name属性即可。

内容的提问来源于stack exchange,提问作者CE_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:04:54