Doctrine 2实体关系删除

时间:2013-05-15 21:16:15

标签: php doctrine-orm zend-framework2

我有一个拥有实体,与“属性”实体有以下关系:

/**
* @ORM\OneToMany(targetEntity="Attribute", mappedBy="entity", cascade={"persist", "remove", "merge"})
**/
protected $attributes;

另一方面,拥有的实体关系如下所示:

/**
* @ORM\ManyToOne(targetEntity="Entity", inversedBy="attributes")
* @ORM\JoinColumn(name="entity_id", referencedColumnName="id")
*/
protected $entity;

当我创建实体的实例时,向其添加属性并保存它。一切正常。 当我从实体中删除一个属性并保持不变时,该属性不会在数据库中删除,并在刷新时重新显示。

有人有想法吗?

2 个答案:

答案 0 :(得分:33)

解决方案

您要找的是orphan removal

如果您想了解目前情况不起作用的详细信息,可以继续阅读。

级联困境

不幸的是,级联操作不会做你想要的。 “cascade = [remove]”只是意味着如果删除了实体对象,那么doctrine将遍历并删除所有子属性:

$em->remove($entity);
// doctrine will basically do the following automatically
foreach ($entity->getAttributes() as $attr)
{
    $em->remove($attr);
}

如何手动完成

如果您需要从实体中删除属性,则删除该属性,如下所示:

$entity->getAttributes()->removeElement($attr);
$em->remove($attribute);

解决方案详情

但是,要自动执行此操作,我们使用孤立删除选项。我们只是告诉学说属性只能属于实体,如果属性不再属于实体,只需删除它:

/**
 * @ORM\OneToMany(targetEntity="Attribute", mappedBy="entity", orphanRemoval=true, cascade={"persist", "remove", "merge"})
 **/
protected $attributes;

然后,您只需执行以下操作即可删除该属性:

$entity->getAttributes()->removeElement($attr);

答案 1 :(得分:2)

使用孤儿删除时要小心。

如果删除元素然后在主实体上调用refresh,则不会从doctrine的内部孤立删除数组中删除该元素。

如果稍后调用flush,将导致从db中删除该条目,忽略刷新。

这看起来像是一个错误,导致我的应用程序中的很多产品丢失图像。我必须实现一个监听器,在他们计划删除之后再次对这些实体调用persist。