#12609·orm

3.7.0 SchemaTool 会默默地删除与同一实体相关的冲突的 STI 关联的外键

作者: HypeMC创建于 2026年9月12日更新于 2026年9月18日

现有行为

在 Doctrine ORM 3.6.8 中,生成的表中包含外键:

sql
CREATE TABLE base (
    id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    dtype VARCHAR(255) NOT NULL,
    ref_id INT NOT NULL,
    PRIMARY KEY (id)
);
CREATE INDEX IDX_C0B4FE6121B741A9 ON base (ref_id);

CREATE TABLE ref (
    id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    PRIMARY KEY (id)
);

ALTER TABLE base
    ADD CONSTRAINT FK_C0B4FE6121B741A9
    FOREIGN KEY (ref_id) REFERENCES ref (id) NOT DEFERRABLE;

在 Doctrine ORM 3.7.0 中,相同的映射生成:

sql
CREATE TABLE base (
    id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    dtype VARCHAR(255) NOT NULL,
    ref_id INT DEFAULT NULL,
    PRIMARY KEY (id)
);
CREATE INDEX IDX_C0B4FE6121B741A9 ON base (ref_id);

CREATE TABLE ref (
    id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    PRIMARY KEY (id)
);

外键被默默地忽略了。

预期行为

我不确定使用任何子实体的配置是否一定正确,因为两个关联提供了相互冲突的元数据。 但是,因为两个关联都目标实体为 同一实体,默默地删除外键似乎是意想不到的。 也许 Doctrine 应该检测到同一个连接列和目标实体的配置不同,并抛出映射异常吗? @greg0ire 你怎么看呢?

如何重现问题

一个简化的映射如下所示:

php
#[ORM\Entity]
#[ORM\InheritanceType('SINGLE_TABLE')]
#[ORM\DiscriminatorColumn(name: 'dtype', type: 'string')]
#[ORM\DiscriminatorMap([
    'one' => ChildOne::class,
    'two' => ChildTwo::class,
    'three' => ChildThree::class,
])]
class Base
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;
}

#[ORM\Entity]
class ChildOne extends Base
{
    #[ORM\ManyToOne(targetEntity: Ref::class)]
    #[ORM\JoinColumn(name: 'ref_id', referencedColumnName: 'id')]
    private ?Ref $ref = null;
}