根据条令2检查违反完整性约束的情况



我正在尝试清理一组实体(用关系术语来说就是一个表),这些实体是Color的实例,我想运行一个使用Doctrine 2删除所有未引用的Color的脚本。问题是Color被系统中的许多其他实体引用。所以,我可以想出两个选择:

  1. 遍历所有颜色,并手动检查每种颜色是否存在对系统上其他实体上特定Color的引用,如果没有引用,则将其删除
  2. 遍历所有颜色并尝试删除其中一种,如果有对该颜色的引用,则捕获由违反完整性约束导致的EM拖掉的异常,因此,我忽略失败的颜色并继续下一个

显然,第二种选择比第一种更简单,所以我试过了。我遇到的问题是,当实体删除失败时,EM会抛出异常,但也会关闭实体管理器,我无法再使用它来删除剩余的颜色!

我在条令2中检查了UnitOfWork类的commit方法,事实上。。。

try {
... //Execute queries
$conn->commit();
} catch (Exception $e) {
$this->em->close();
$conn->rollback();
throw $e;
}

有什么方法可以完成我想要做的事情吗(也许重新打开实体经理)
你认为还有更好的方法吗
为什么教义会有这种行为?

还请注意,我正在将条令2与Symfony 2一起使用

理想情况下,您应该在关系中定义orphanRemoval,这样您就不需要为删除而烦恼。除此之外,我现在可以想出三个解决方案。。

首先,在引用colors表时,是否在ON DELETE中使用CASCADE

1)

如果你确实使用CASCADE,我建议按照这里描述的方式实现Doctrine的批处理:批量删除,但这里你的$batchSize正好是1。

2)

I、 不知何故,将上述解决方案视为效率不高,您也可以通过以下方式实现:

  • 遍历引用Color实体的实体,并将Colorid收集到数组中
  • 如果该数组不为空,则执行:DELETE FROM AcmeDemoBundle:Color c WHERE c.id IN (:ids)并像往常一样设置ids参数

3)

如果使用CASCADE,还有另一种解决方案。您可以执行原始sql:

DELETE IGNORE FROM color;

在这里,引用的颜色不会被删除,并且会引发错误,但由于IGNORE,它最终只会作为警告。

希望这些能有所帮助。。。。

类似这样的东西:

// somewhere in ColorRepository.php
$this->createQueryBuilder("o")
->leftJoin("o.Relation1", "r1")
->leftJoin("o.Relation2", "r2)
->where("r1 IS NULL AND r2 IS NULL")
->delete() ;

只有当实体(Color)不再与r1和r2有关系时,才应该加载它们并将其删除。

相关内容

  • 没有找到相关文章

最新更新