Php 原则2实体关系消除

Php 原则2实体关系消除,php,doctrine-orm,zend-framework2,Php,Doctrine Orm,Zend Framework2,我拥有一个与“属性”实体具有以下关系的拥有实体: 另一方面,拥有的实体关系如下所示: /** * @ORM\ManyToOne(targetEntity="Entity", inversedBy="attributes") * @ORM\JoinColumn(name="entity_id", referencedColumnName="id") */ protected $entity; 创建实体实例时,向其添加属性并保存。一切都很好。 当我从实体中删除一个属性并将其持久化时,该属性不会在数

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

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

/**
* @ORM\ManyToOne(targetEntity="Entity", inversedBy="attributes")
* @ORM\JoinColumn(name="entity_id", referencedColumnName="id")
*/
protected $entity;
创建实体实例时,向其添加属性并保存。一切都很好。 当我从实体中删除一个属性并将其持久化时,该属性不会在数据库中删除,并在刷新时重新显示

有人有想法吗?

解决方案 你要找的是

如果你想了解为什么你目前的状况不起作用的细节,你可以继续阅读

级联灾难 不幸的是,级联操作无法实现您想要的功能。“cascade=[remove]”仅仅意味着如果实体对象被删除,那么条令将循环并删除所有子属性:

$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);

使用孤立移除时要小心

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

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


对我来说,这看起来像一个bug,并导致我的应用程序中很多产品的图像丢失。我必须实现一个侦听器,在这些实体被安排删除之后,再次调用persist

多亏了你,我现在可以部分工作了。只是有一件小事情不能正常工作。当属性实体设置为null并从实体的数组集合中删除时,它只是在数据库中将属性实体id设置为null,并且在我持久化实体时不会删除它。我的道歉。我已经更新了我的答案。您不应该取消设置实体,您只需要将其从属性集合中删除。这个答案非常正确。在外部实体上执行$em->remove()的问题在于,本地实体在刷新之前被持久化,这将使外部实体返回,即使您已将其删除——因为我们正在级联持久化。是的,一定要从集合中删除,那么根本不需要$em->remove()。
$entity->getAttributes()->removeElement($attr);