2013-09-28 2 views
8

Doctrine에서 단방향 ManyToMany 관계에 문제가 있습니다. 이 케이스는 매우 쉽습니다 : 제품에 많은 태그가 있습니다. 태그는 제품뿐만 아니라 내 모델의 "태그 지정 가능"엔티티에도 첨부 할 수 있습니다. 다음은 내 코드 스 니펫입니다.Doctrine 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 클래스의 단방향 관계 코드가 생략되었으므로 나는에 연결된 일부 태그가 제품을 제거하려는

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 | 

: 같은 정의 협회

교리는 (생략됩니다 제품 테이블 및 태그 테이블에 대한 SQL) 다음 SQL 코드를 생성합니다.

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

그것은 분명히 인해 무결성 제약 조건 위반에 실패 ("삭제하거나 부모 행을 업데이트 할 수 없습니다 : 외래 키 제약 조건이 실패 (products_tags는, CONSTRAINT FK_E3AB5A2CBAD26311 FOREIGN KEY (tag_id는) 참고 문헌 tags (id)) '").

외래 키에 ON DELETE CASCADE를 추가하는 products_tags 테이블을 변경하면 원하는대로 작동합니다. 나는 products_tags 테이블에서 참조 된 행을 자동으로 제거하는 TAG ($ em-> remove ($ tag)) 및 PRODUCT ($ em-> remove ($ product))를 쉽게 제거 할 수 있습니다 ..

products_tags를 얻으려면 어떻게해야합니까? CASCADE DELETE 외래 키가있는 테이블? 이미 캐스케이드 = { "all"}에 지쳤으나 실패했습니다.

제품 태그 컬렉션에서 모든 태그를 제거 할 수 있습니다. 단지 엔티티 관리자 오브젝트의 메소드를 제거 호출하여 한 번에 그것을 얻을 수 있습니다.

합니까 교리가 정말 부족?

답변

22

좋아, 나는 Doctrine2 문서를 파헤쳐 관리했다. 해결책은 onDelete = "cascade" to @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 = "캐스케이드"데이터베이스 레벨에있는 동안, (앱에서) 개체 수준에서 관리됩니다.

관련 문제