Doctrine ManyToMany关联删除时自动清理中间表关联记录实现方案
Doctrine ManyToMany关联中间表同步删除方案
核心问题说明
orphanRemoval配置仅对OneToMany/OneToOne关联生效,无法作用于ManyToMany关联,这是你之前配置后没有效果的根本原因。
可选实现方案
方案1:单向关联配置数据库级联(无需修改User实体,推荐)
不需要在User实体新增任何字段,直接修改Project实体的关联注解,给中间表的两个外键都配置数据库级联删除即可同时满足删除Project、删除User时自动清理中间表关联行的需求:
/** * @ORM\Entity(repositoryClass=ProjectRepository::class) */ class Project { ... /** * @ORM\ManyToMany(targetEntity=User::class) * @ORM\JoinTable( * joinColumns={@ORM\JoinColumn(onDelete="CASCADE")}, * inverseJoinColumns={@ORM\JoinColumn(onDelete="CASCADE")} * ) */ private $userProjectManagers; ... }
joinColumns对应关联中间表指向Project表的外键,onDelete="CASCADE"配置后删除Project时,数据库会自动删除中间表所有关联该Project的行inverseJoinColumns对应关联中间表指向User表的外键,onDelete="CASCADE"配置后删除User时,数据库会自动删除中间表所有关联该User的行
方案2:配置双向关联
你猜测的新增mappedBy/inversedBy的方案是可行的,且不属于不良实践:反向关联是Doctrine ORM的标准用法,即使暂时没有业务侧读取需求,仅用于维护关联一致性也是完全合理的。
- 修改Project实体的关联注解,指定
inversedBy指向User实体的对应字段:
/** * @ORM\ManyToMany(targetEntity=User::class, inversedBy="managedProjects") */ private $userProjectManagers;
- 在User实体中新增反向关联字段:
/** * @ORM\ManyToMany(targetEntity=Project::class, mappedBy="userProjectManagers") */ private $managedProjects; public function __construct() { $this->managedProjects = new \Doctrine\Common\Collections\ArrayCollection(); }
注:该方案建议同时搭配方案1的onDelete="CASCADE"配置,避免ORM层面漏处理关联导致删除失败
生效操作
修改完注解配置后,需要执行以下命令更新数据库结构才能生效:php bin/console make:migrationphp bin/console doctrine:migrations:migrate
内容的提问来源于stack exchange,提问作者MadLuca
相关产品推荐
相关产品推荐

