I have an owning entity that has the following relation to an "attribute" entity:
/**
* @ORM\OneToMany(targetEntity="Attribute", mappedBy="entity", cascade={"persist", "remove", "merge"})
**/
protected $attributes;
On the side, the owned entity relation looks like this:
/**
* @ORM\ManyToOne(targetEntity="Entity", inversedBy="attributes")
* @ORM\JoinColumn(name="entity_id", referencedColumnName="id")
*/
protected $entity;
When I create an instance of an entity, add attributes to it and save it. It all works fine. When I remove one attribute from the entity and persist, the attribute is not deleted in the database and re-appears upon refresh.
Anyone has an idea?
What you're looking for is orphan removal.
You can read on if you'd like details on why your current situation isn't working.
The cascade operation won't do what you want unfortunately. The "cascade=[remove]" just means that if the entity object is removed then doctrine will loop through and remove all child attributes as well:
$em->remove($entity);
// doctrine will basically do the following automatically
foreach ($entity->getAttributes() as $attr)
{
$em->remove($attr);
}
If you needed to remove an attribute from an entity you'd delete the attribute like so:
$entity->getAttributes()->removeElement($attr);
$em->remove($attribute);
But, to do that automatically we use the orphan removal option. We simply tell doctrine that attributes can only belong to entities, and if an attribute no longer belongs to an entity, simply delete it:
/**
* @ORM\OneToMany(targetEntity="Attribute", mappedBy="entity", orphanRemoval=true, cascade={"persist", "remove", "merge"})
**/
protected $attributes;
Then, you can remove the attribute by simply doing this:
$entity->getAttributes()->removeElement($attr);
Be careful when using orphan removal.
If you remove an element and then call refresh on the main entity the element is not removed from the internal orphan removal array of doctrine.
And if flush is called later, will result in removing that entry from the db, ignoring the refresh.
This looks like a bug to me, and resulted in loss of images on a lot of products in my app. I had to implement a listener to call persist again on those entities, after they ware scheduled for delete.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With