禁用Doctrine外键约束

14 浏览
0 Comments

禁用Doctrine外键约束

我在我的模型中有一个关系:

/**
* @ORM\ManyToOne(targetEntity="Page", cascade="persist")
* @ORM\JoinColumn(name="page_id", referencedColumnName="id")
*/
private $parentPage;

当我删除父页面时,我会遇到以下错误:

完整性约束冲突:1451 无法删除或更新父行:外键约束失败

基本上,我的模型有一个页面和页面修订。当我删除页面时,我不想删除修订。我也想保留页面修订的page_id(即不将其设置为null)。

如何使用Doctrine实现这一点?

0
0 Comments

在Symfony 4.3中,我通过重写Doctrine的一个类来解决了这个问题。具体的代码如下所示:


在这个类中,我重写了`supportsForeignKeyConstraints`和`supportsForeignKeyOnUpdate`方法,将它们的返回值都设为false,以禁用数据库中的外键约束。这是因为我在使用分区功能时不需要外键约束。

以上就是我解决这个问题的方法。通过重写Doctrine的类,我成功地禁用了外键约束,以满足我的需求。

0
0 Comments

禁用Doctrine外键约束的原因是为了在特定的模型中禁用外键导出。为了解决这个问题,可以在模型的属性中设置export选项,将其值设置为none,这样只会导出表的定义而不包含外键。除了none之外,还可以设置为tables, constraints, plugins或all。

0
0 Comments

问题原因:根据定义,如果没有将外键设置为null(onDelete="SET NULL")或级联删除操作(cascade={"remove"} | onDelete="CASCADE"),则无法删除指向外键的记录。

解决方法:一种解决方法是软删除(已经提到)。另一种方法是在删除之前,在preRemove事件处理程序(生命周期回调)中将一个额外的removed_page_id列与page_id同步。以下是代码示例:

在Revision类中:

/**
 * \ManyToOne(targetEntity="Page", cascade="persist")
 * \JoinColumn(name="page_id", referencedColumnName="id", onDelete="SET NULL")
 */
private $parentPage;
/**
 *  int
 * \Column(type="integer", name="removed_page_id", nullable=true)
 */
protected $removedPageId;

然后在Page类中:

/** 
 * \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();
}

或者,您当然可以在构建Revision对象时已经设置正确的removedPageId值,那么您甚至不需要在删除时执行生命周期回调。

保证约束需要额外的计算资源。应用程序服务器比数据库服务器更容易进行水平扩展,因此约束应该放在业务逻辑中。

0