Doctrine级联更新 - 在更新

时间:2015-06-16 17:16:47

标签: mysql database symfony doctrine-orm innodb

我有Promotion个实体与PromotionCategory个实体有一对多的关系。

Promotion实体中我有:

/**
 * @var PromotionCategory[]
 * @OneToMany(targetEntity="AwinServices\Modules\AdvertiserPromotion\DomainLayer\Models\Promotion\Category", mappedBy="promotion", cascade={"persist", "remove"})
 */
public $promotionCategories;

PromotionCategory实体中我有:

/**
 * @ManyToOne(targetEntity="AwinServices\Modules\AdvertiserPromotion\DomainLayer\Models\Promotion", inversedBy="promotionCategories")
 * @JoinColumn(name="promotionId", referencedColumnName="promotionId")
 **/
public $promotion;

我遇到的问题是,每当我使用新类别更新促销时,它都会继续为该促销创建新的PromotionCategory实体。

我想要的是重置该促销的先前类别,并为我传递的类别创建新行。

要解决此问题,我现在尝试在持久使用DQL DELETE语句之前删除该促销的所有类别:

$q = $this->doctrineEntityManager->createQuery("Delete from " . $this->getEntityClassname() . " r where r.promotion =" . $promotion->id);
$q->execute();

我认为Doctrine会自动执行此操作,就像对ManyToMany关系一样,并且不明白为什么即使提到cascade={"persist", "remove"}

之后它也不能为我的情况做这件事

有更清洁的方法吗?

1 个答案:

答案 0 :(得分:1)

首先,cascade={"persist", "remove"}仅适用于您持久保存或删除Promotion对象的PromotionCategory 的情况。您尝试执行的操作是删除Promotion对象的PromotionCategory子项,因此cascade关键字在这种情况下无关紧要。

话虽如此,您的查询问题在于您未在查询中加入Promotion实体。在DELETE语句中,Doctrine显然无法做到这一点,如SO post所示。

正如@Danielle Suurlant在该帖子中所说,一种方法是从数据库中获取要删除的PromotionCategory个实体,然后使用实体管理器删除它们:

$qb = $this->entityManager->createQueryBuilder();
$query = $qb->select('AwinServices\Modules\AdvertiserPromotion\DomainLayer\Models\Promotion\Category', 'category')
  ->innerJoin('category.promotion', 'promotion')
  ->where('promotion.id = :promotion_id')
  ->setParameter('promotion_id', $promotion->id)
  ->getQuery();
$results = $query->execute(); 

然后迭代结果并删除它们:

foreach ($results as $result) {
  $this->entityManager->remove($result);
}

然后冲洗掉它们:

$this->entityManager->flush();

再次感谢Danielle Suurlant在another post中对这个类似问题的回答。