Symfony3执行Doctrine迁移报错:引用列iso3不存在
问题根因
你的映射配置有3处核心错误,直接导致Doctrine无法识别关联关系:
- 多对多注解的
inversedBy参数配置错误:该参数要求填写目标实体上对应反向关联的属性名,而非目标实体的主键字段名,你当前填的iso3是Country的主键字段名,不是关联属性名。 - 关联注解位置错误:你把Country侧的
@ManyToMany、@OneToMany注解直接写在了主键属性$iso3上,Doctrine会将该属性识别为普通主键字段,不会将其解析为关联属性,自然无法找到你引用的关联字段。 - 中间表外键配置颠倒:
@JoinTable配置中,joinColumns对应**当前实体(LineItem)在中间表的外键,inverseJoinColumns对应目标实体(Country)**在中间表的外键,你当前将两个外键的配置完全写反了。
修复方案
按以下步骤调整实体映射即可:
- 调整Country实体的注解位置
将关联注解从主键$iso3上剥离,单独定义关联属性,主键属性只保留字段、主键相关的注解,参考代码如下:
class Country { // ...其他属性 /** * @ORM\Column(name="iso3", type="string", length=10, unique=true) * @ORM\Id() * @ORM\GeneratedValue(strategy="NONE") */ private $iso3; /** * @ORM\ManyToMany(targetEntity="LineItem", mappedBy="countryFilter") */ private $lineItems; /** * @ORM\OneToMany(targetEntity="Region", mappedBy="country") */ private $regions; public function __construct() { $this->lineItems = new \Doctrine\Common\Collections\ArrayCollection(); $this->regions = new \Doctrine\Common\Collections\ArrayCollection(); } // ...补全对应属性的getter、setter方法 }
- 修正LineItem实体的多对多映射配置
将inversedBy参数值改为Country侧新建的关联属性名lineItems,同时调换中间表两个外键的对应关系,参考代码如下:
class LineItem { // ...其他属性 /** * @ORM\ManyToMany(targetEntity="CampaignBundle\...\Country", inversedBy="lineItems") * @ORM\JoinTable( * name="lineitem_country_filter", * joinColumns={ * @ORM\JoinColumn(name="lineitem_id", referencedColumnName="id") * }, * inverseJoinColumns={ * @ORM\JoinColumn(name="country_iso3", referencedColumnName="iso3") * } * ) */ private $countryFilter; public function __construct() { $this->countryFilter = new \Doctrine\Common\Collections\ArrayCollection(); } // ...补全对应属性的getter、setter方法 }
- 验证配置后生成迁移
先执行映射校验命令确认配置无错:php app/console doctrine:schema:validate
确认输出映射合法后,再执行迁移生成命令即可正常生成中间表结构:php app/console doctrine:migrations:diff
注意:中间表存储Country iso3值的字段会自动匹配主键字段的类型、长度(string(10)),无需手动修改外键字段配置,不会改动你现有Country表的主键设计。
内容的提问来源于stack exchange,提问作者Gracjan
相关产品推荐
相关产品推荐

