我正在尝试清理一组实体(即一个表,在关系术语中),这些实体是Color
的实例,我想运行一个使用Doctrine 2删除的脚本所有未引用的Color
。问题是系统中的许多其他实体引用了Color
。所以,我可以想到两个选择:
Color
的引用,如果没有引用,则删除它。显然,第二种选择比第一种更简单,所以我试过了。我遇到的问题是,当一个实体删除失败时,EM抛出一个异常,但也关闭了实体管理器,我不能再用它来删除剩余的颜色了!
我在Doctrine 2中检查commit
类的UnitOfWork
方法,实际上......
try {
... //Execute queries
$conn->commit();
} catch (Exception $e) {
$this->em->close();
$conn->rollback();
throw $e;
}
有没有办法完成我想要做的事情(也许重新开放实体经理)?
你相信有更好的方法吗?
为什么Doctrine有这种行为?
另请注意我在Symfony 2中使用Doctrine 2
答案 0 :(得分:1)
理想情况下,您可以在关系中定义orphanRemoval
,这样您就不必费心去除。除此之外,我现在可以想到3个解决方案..
首先,在引用CASCADE
表时,您是否在ON DELETE
中使用colors
?
如果您确实使用CASCADE
,我建议您按照此处所述的方式实施Doctrine的批处理:BULK DELETE但此处您的$batchSize
恰好是1。
我,不知何故,看到上述解决方案效率不高,你也可以通过以下方式实现:
Color
实体的实体,并将id
Color
收集到数组中。DELETE FROM AcmeDemoBundle:Color c WHERE c.id IN (:ids)
并照常设置ids
参数。如果不使用CASCADE
,还有另一种解决方案。您可以执行原始SQL :
DELETE IGNORE FROM color;
此处,引用的颜色不会被删除,并会触发错误,但由于IGNORE
,它最终只会作为警告。
希望其中一些有帮助......
答案 1 :(得分:0)
这样的事情:
// somewhere in ColorRepository.php
$this->createQueryBuilder("o")
->leftJoin("o.Relation1", "r1")
->leftJoin("o.Relation2", "r2)
->where("r1 IS NULL AND r2 IS NULL")
->delete() ;
只有当它们与r1和r2没有关系并删除它们时才会加载你的实体(Color)。