2013-09-28 81 views
8

我有單向ManyToMany關係在教義中的問題。案例非常簡單:產品有很多標籤。標籤可以附加到產品,也可以附加到我的模型中的任何「標籤」實體。這裏是我的代碼片段:學說ManyToMany:刪除對象

/** 
* @Entity 
* @Table(name="products") 
**/ 
class Product { 

    /** some other fields here */ 

    /** 
    * @ManyToMany(targetEntity="Tag") 
    * @JoinTable(name="products_tags", 
    *  joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@JoinColumn(name="tag_id", referencedColumnName="id")}  
    *  ) 
    */ 
    protected $tags; 

} 

由於它的Tag類的單向關係代碼被省略。

對於這樣定義的關聯學說生成以下SQL代碼(SQL產品表和標籤表將被跳過):

CREATE TABLE `products_tags` (
    `product_id` int(11) NOT NULL, 
    `tag_id` int(11) NOT NULL, 
    PRIMARY KEY (`product_id`,`tag_id`), 
    KEY `IDX_E3AB5A2C4584665A` (`product_id`), 
    KEY `IDX_E3AB5A2CBAD26311` (`tag_id`), 
    CONSTRAINT `FK_E3AB5A2CBAD26311` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`), 
    CONSTRAINT `FK_E3AB5A2C4584665A` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci | 

我想刪除具有附着到它的一些標籤產品。

/* $product is already persisted, $em is an Entity Manager */ 
$em->remove($product); 
$em->flush(); 

這顯然由於失敗的完整性約束違約(「不能刪除或更新父行,外鍵約束失敗(products_tags,約束FK_E3AB5A2CBAD26311外鍵(tag_id)參考文獻tagsid))「」)。

當我改變products_tags表添加ON DELETE CASCADE到外鍵它工作正如我想。我可以很容易地刪除TAG($ em-> remove($ tag))和PRODUCT($ em-> remove($ product),它們可以自動從products_tags表中刪除引用行。

我的代碼應該如何獲得products_tags我已經厭倦了cascade = {「all」}但它失敗了。

我知道,我可以從產品的標記集合中刪除所有標記,但正如我所提到的,我想要實現這一步,只是通過調用刪除實體管理對象的方法。

是否真的學說缺乏呢?

回答

22

好,我通過挖掘Doctrine2文檔來管理自己;)解決方案是將onDelete =「cascade」添加到@JoinColumn

/** 
* @Entity 
* @Table(name="products") 
**/ 
class Product { 

    /** some other fileds here */ 

    /** 
    * @ManyToMany(targetEntity="Tag") 
    * @JoinTable(name="products_tags", 
    *  joinColumns={@JoinColumn(name="product_id", referencedColumnName="id", onDelete="cascade")}, 
    *  inverseJoinColumns={@JoinColumn(name="tag_id", referencedColumnName="id", onDelete="cascade")}  
    *  ) 
    */ 
    protected $tags; 

} 

需要注意的是,級聯= {「所有」}是在對象級別(在您的應用程序)管理,而onDelete =「級聯」是在數據庫級別。