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

如何使用Doctrine创建自关联表的外键

Doctrine单表自关联外键未生成问题解决

我正在学习Doctrine,尝试在单表内通过外键建立两列的关联关系,以下是我的Entity类:

#[ORM\Entity(repositoryClass: BranchRepository::class)]
#[ORM\Table(name: "tst_branches")]
class Branch
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer')]
    private int $id;

    #[ORM\Column(type: 'integer')]
    #[ORM\ManyToOne(
        targetEntity: Branch::class,
        inversedBy: 'id'
    )]
    private int $parent_id;
}

随后我通过以下命令创建数据库结构:

bin/console doctrine:schema:create

结果生成了预期的两列,但未创建连接parent_id与id列的外键。

当前数据库表结构

请问需要修改哪些内容才能在数据库结构中生成外键?

预期效果如下:
预期数据库表结构


问题原因与修改方案

你的代码存在两个核心问题:

  • 关联注解与字段类型不匹配:$parent_id字段被定义为int类型,但Doctrine的关联字段应对应关联对象(而非原始ID值),且#[ORM\Column]注解不能与关联注解混用——关联字段的列定义由Doctrine自动处理。
  • inversedBy参数错误:inversedBy需指向当前实体中对应反向关联的属性名,而非主键id。自关联的ManyToOne需要搭配对应的OneToMany反向关联。

修改后的实体类代码

#[ORM\Entity(repositoryClass: BranchRepository::class)]
#[ORM\Table(name: "tst_branches")]
class Branch
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    #[ORM\Column(type: 'integer')]
    private int $id;

    // 移除#[ORM\Column]注解,字段类型改为关联对象Branch|null
    #[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'children')]
    // 显式指定外键列名,确保与预期一致
    #[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id', nullable: true)]
    private ?Branch $parent = null;

    // 添加反向OneToMany关联,用于关联当前分支的子分支
    #[ORM\OneToMany(mappedBy: 'parent', targetEntity: self::class)]
    private Collection $children;

    // 构造函数初始化Collection对象
    public function __construct()
    {
        $this->children = new ArrayCollection();
    }

    // 可选:添加必要的 getter/setter 方法
    public function getId(): int
    {
        return $this->id;
    }

    public function getParent(): ?Branch
    {
        return $this->parent;
    }

    public function setParent(?Branch $parent): self
    {
        $this->parent = $parent;
        return $this;
    }

    public function getChildren(): Collection
    {
        return $this->children;
    }
}

执行数据库结构更新

修改完成后,重新生成数据库结构:

# 若为新表,直接重新创建
bin/console doctrine:schema:drop --force
bin/console doctrine:schema:create

# 若已有数据,使用更新命令
# bin/console doctrine:schema:update --force

关键说明

  • 关联字段必须定义为实体对象类型(如?Branch),而非原始ID类型,Doctrine会自动处理ID的存储与映射逻辑。
  • #[ORM\JoinColumn]可显式指定外键列名、是否允许为空等属性,确保生成的外键完全符合预期。
  • 反向关联OneToMany虽非生成外键的强制要求,但能保证Doctrine实体关联操作的完整性,建议添加。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:45:01