I have a Promotion Entity having a One-to-Many relationship with PromotionCategory Entities.
In the Promotion Entity I have:
/**
* @var PromotionCategory[]
* @OneToMany(targetEntity="AwinServices\Modules\AdvertiserPromotion\DomainLayer\Models\Promotion\Category", mappedBy="promotion", cascade={"persist", "remove"})
*/
public $promotionCategories;
And in the PromotionCategory Entity I have:
/**
* @ManyToOne(targetEntity="AwinServices\Modules\AdvertiserPromotion\DomainLayer\Models\Promotion", inversedBy="promotionCategories")
* @JoinColumn(name="promotionId", referencedColumnName="promotionId")
**/
public $promotion;
The problem I am having is that every time I update a Promotion with a new Category, it keeps on creating new PromotionCategory entities for that Promotion.
What I want is to reset the previous categories for that Promotion, and create new rows for the categories I am passing.
To solve the issue currently I am trying to remove all the Categories for that promotion before persisting using a DQL DELETE statement:
$q = $this->doctrineEntityManager->createQuery("Delete from " . $this->getEntityClassname() . " r where r.promotion =" . $promotion->id);
$q->execute();
I assumed Doctrine will do that automatically as it does for ManyToMany relationships and don't understand why it doesn't do this for my case even after mentioning cascade={"persist", "remove"}
Is there a cleaner way of doing this?
Firstly,
cascade={"persist", "remove"}only applies if you persist or remove thePromotionparent of thePromotionCategoryobject. What you're trying to do is remove thePromotionCategorychildren of a Promotion object, so thecascadekeyword is irrelevant in this case.That being said, the problem with your query is that you're not joining on the Promotion entity in your query. Doctrine apparently has trouble doing this in
DELETEstatements, as can be seen in this SO post.As @Danielle Suurlant says in that post, one way to do this is to fetch the
PromotionCategoryentities you want to remove from the database, and then just remove them with the entity manager:Then iterate over the results and remove them:
And flush to get rid of them:
Thanks again to Danielle Suurlant for her answer to this similar problem in another post.