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 thePromotion
parent of thePromotionCategory
object. What you're trying to do is remove thePromotionCategory
children of a Promotion object, so thecascade
keyword 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
DELETE
statements, as can be seen in this SO post.As @Danielle Suurlant says in that post, one way to do this is to fetch the
PromotionCategory
entities 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.