问题描述
我在一种模型上有关系:
I have a relationship on one of my models:
/**
* @ORM\ManyToOne(targetEntity="Page", cascade="persist")
* @ORM\JoinColumn(name="page_id", referencedColumnName="id")
*/
private $parentPage;
当我删除父页面时,出现此错误:
And when I delete the parent page, I get this error:
Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails
基本上我的模型是页面和页面修订版。删除页面时,我不想删除。我也想在页面修订版上保留 page_id
(即不要将其设置为null)。
Basically my models are a page, and page revision. When I delete the page I don't want to delete the revisions. I also want to keep the page_id
on the page revisions (i.e. not set it to null).
如何我是用Doctrine做的吗?
How can I do this with Doctrine?
推荐答案
通过定义,您不能删除外键为指向而不将键设置为null( onDelete = SET NULL
)或级联删除操作(-ORM级别: cascade = { remove}
|数据库级别: onDelete = CASCADE。
)。
还有,但是您必须手动执行此操作,我不认为Doctrine支持此现成的
(如果我错了,请纠正我,但是在这种情况下无论如何都不要设置默认值。)
By definition you cannot delete the record that the foreign key is pointing at without setting the key to null (onDelete="SET NULL"
) or cascading the delete operation (There are two options - ORM Level: cascade={"remove"}
| database level: onDelete="CASCADE"
).
There is the alternative of setting a default value of a still existing record, but you have to do that manually, I don't think Doctrine supports this out-of-the-box
(please correct me if I am wrong, but in this case setting a default value is not desired anyway).
这种严格性反映了具有外键约束的概念;就像@Théo所说:
This strictness is reflecting the concept of having foreign key constraints; like @Théo said:
软删除(已经提到)是一种解决方案,但是您还可以做的是添加一个额外的 removed_page_id
列您与 page_id
进行了同步,就在 preRemove
事件处理程序中将其删除之前(生命周期回调)。这些信息是否具有任何价值,我想知道,但我想您对此有一定用处,否则您不会问这个问题。
Soft delete (already mentioned) is one solution, but what you could also do is add an additional removed_page_id
column that you sync with the page_id
just before you delete it in a preRemove
event handler (life cycle callback). Whether such information has any value I wonder but I guess you have some use for it, otherwise you wouldn't ask this question.
我肯定是不主张这是一个好习惯,但这至少可以用于边缘情况。因此,符合以下条件的行:
I am definitely not claiming this is good practice, but it is at least something that you can use for your edge case. So something in the line of:
在您的修订版
中:
/**
* @ORM\ManyToOne(targetEntity="Page", cascade="persist")
* @ORM\JoinColumn(name="page_id", referencedColumnName="id", onDelete="SET NULL")
*/
private $parentPage;
/**
* @var int
* @ORM\Column(type="integer", name="removed_page_id", nullable=true)
*/
protected $removedPageId;
然后在您的页面
中:
/**
* @ORM\PreRemove
*/
public function preRemovePageHandler(LifecycleEventArgs $args)
{
$entityManager = $args->getEntityManager();
$page = $args->getEntity();
$revisions = $page->getRevisions();
foreach($revisions as $revision){
$revision->setRemovedPageId($page->getId());
$entityManager->persist($revision);
}
$entityManager->flush();
}
当然,您可能已经设置了正确的 $在构造
的值,那么您甚至不需要在remove上执行生命周期回调。修订版
的过程中,如果您删除了RemovePageId
Alternatively you could of course already set the correct $removedPageId
value during construction of your Revision
, then you don't even need to execute a life cycle callback on remove.
这篇关于禁用原则外键约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!