我有一个具有这种关系的实体:
/**
* @ORM\OneToOne(targetEntity="App\Entity\Contract", inversedBy="childContract", cascade={"persist", "remove"})
*/
private $parentContract;
/**
* @ORM\OneToOne(targetEntity="App\Entity\Contract", mappedBy="parentContract", cascade={"persist", "remove"})
*/
private $childContract;
我的模式已生成,我一直在处理这个问题,直到现在,我决定删除
"remove"
部分:
/**
* @ORM\OneToOne(targetEntity="App\Entity\Contract", inversedBy="childContract", cascade={"persist"})
*/
private $parentContract;
/**
* @ORM\OneToOne(targetEntity="App\Entity\Contract", mappedBy="parentContract", cascade={"persist"})
*/
private $childContract;
但是如果我执行命令:
bin/console doctrine:schema:update --dump-sql
我得到输出:
[确定]无需更新 - 您的数据库已与当前实体元数据同步。
事实是,当我尝试删除合同时,Doctrine 尝试删除子合同,并且我收到此异常(即,它正在尝试删除子合同):
执行“DELETE FROM Contract WHERE id = ?”时发生异常参数[2098]: SQLSTATE[23000]:完整性约束违规:1451 无法删除或更新父行:外键约束失败(
.prestazoom
,CONSTRAINTcontract
FOREIGN KEY (FK_E98F28594E5AF28D
) REFERENCESparent_contract_id
(contract
))id
)
如果我使用此 SQL 命令检查此表的约束:
SELECT
r.CONSTRAINT_NAME,
r.DELETE_RULE,
r.TABLE_NAME,
GROUP_CONCAT(k.COLUMN_NAME SEPARATOR ', ') AS `constraint columns`,
r.REFERENCED_TABLE_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS r
JOIN information_schema.KEY_COLUMN_USAGE k
USING (CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME)
-- using MySQL's GROUP BY clause. In other DB's more columns would need to be
-- specified!
WHERE r.CONSTRAINT_SCHEMA = 'prestazoom' and r.TABLE_NAME = 'contract'
GROUP BY r.CONSTRAINT_CATALOG,
r.CONSTRAINT_SCHEMA,
r.CONSTRAINT_NAME;
我得到这个输出:
| FK_E98F28594E5AF28D | RESTRICT | contract | parent_contract_id | contract |
哪个不是级联删除?我真的不知道,也不知道为什么它要尝试删除子合同。
不是检测到我取消了“级联”限制吗?难道是别的问题?
删除对象/条目时,您需要指定关系级别的行为。在这里,您希望在删除子项时
parentContract
为空。
在 Doctrine 中,您可以使用
onDelete
属性来实现这一点。
/**
* @ORM\OneToOne(targetEntity="App\Entity\Contract", inversedBy="childContract", cascade={"persist"}, onDelete="SET NULL")
*/
private $parentContract;
/**
* @ORM\OneToOne(targetEntity="App\Entity\Contract", mappedBy="parentContract", cascade={"persist"})
*/
private $childContract;