2011-03-16 53 views
5

我有一個ZendFramework 1.11.2中使用Doctrine 2作爲ORM的雙向OneToMany關係。doctrine2 OneToMany關係插入NULL作爲外鍵

注意:Doctrine沒有創建數據庫表。數據庫是MySQL。

由於某些原因,當我堅持並刷新鏈接實體到鏈接表(見下文)時,外鍵字段(container_id)被設置爲NULL。但是,如果從'ManyToOne(targetEntity =「Shepherd \ Navigation \ Domain \ Container \ Model」,inversedBy =「links」)'行中刪除'@'符號,則會正確填充外鍵字段。

由於實體在刪除'@'符號時已正確添加到數據庫,因此OneToMany關係在某處出現問題。

舉例來說,如果我有一個名爲$鏈路的鏈路模型(見下面的僞代碼)...

$link (Shepherd\Navigation\Domain\Link\Model) 
    { 
     id: ''  // auto generated value 
     cid: 23  // the foreign key value 
     label: test 
     uri: test.com 
     ...   // other values not listed here for brevity 
    } 

...當新的鏈路模型被持久化和實體管理器被刷新,鏈接(shepherd_navigation_link)表中新插入的行的container_id(外鍵)值爲NULL。

$em // Assume $em is the Entity Manager 
    $em->persist($link); 
    $em->flush(); 

    // The container_id in the newly added row in the 
    // link table (shepherd_navigation_link) is NULL 

鏈接表模式:

CREATE TABLE `shepherd_navigation_link` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `container_id` int(10) unsigned DEFAULT NULL, 
    `node_id` int(10) unsigned DEFAULT NULL, 
    `parent_id` int(10) unsigned DEFAULT NULL, 
    `label` varchar(100) NOT NULL, 
    `options` text, 
    `events` text, 
    `privilege` varchar(100) NOT NULL, 
    `resource` varchar(100) DEFAULT NULL, 
    `uri` varchar(300) NOT NULL, 
    `visible` int(10) unsigned DEFAULT '1', 
    PRIMARY KEY (`id`), 
    KEY `container_id` (`container_id`) 
) ENGINE=InnoDB 
ALTER TABLE `shepherd_navigation_link` ADD FOREIGN KEY (container_id) REFERENCES shepherd_navigation_container(id) 

鏈路實體模型:

/** 
* @Entity 
* @Table(name="shepherd_navigation_link") 
*/ 
class 
{ 
    /** 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue 
    */ 
    protected $id; 

    /** 
    * @Column(name="container_id", type="integer", nullable=false) 
    */ 
    protected $cid; 

    /** 
    * @Column(name="node_id", type="integer") 
    */ 
    protected $nid; 

    /** 
    * @Column(name="parent_id", type="integer", nullable=false) 
    */ 
    protected $pid; 

    /** 
    * @Column 
    */ 
    protected $label; 

    /** 
    * @Column(nullable=true) 
    */ 
    protected $options; 

    /** 
    * @Column(nullable=true) 
    */ 
    protected $events; 

    /** 
    * @Column 
    */ 
    protected $privilege; 

    /** 
    * @Column(nullable=true) 
    */ 
    protected $resource; 

    /** 
    * @Column 
    */ 
    protected $uri; 

    /** 
    * @Column(type="integer", nullable=true) 
    */ 
    protected $visible; 

    /** 
    * @OneToMany(targetEntity="Model", mappedBy="parent") 
    */ 
    private $children; 

    /** 
    * @ManyToOne(targetEntity="Model", inversedBy="children") 
    */ 
    private $parent; 

    /** 
    *) @ManyToOne(targetEntity="Shepherd\Navigation\Domain\Container\Model", inversedBy="links" 
    */ 
    private $container; 

    /** 
    * @OneToOne(targetEntity="Shepherd\Navigation\Domain\Link\Position", inversedBy="link") 
    */ 
    private $node; 

    public function __construct() 
    { 
     $this->children = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** Accessors and Mutators excluded for brevity **/ 
} 

注:受保護的屬性$ CID映射到以上CONTAINER_ID列。

容器表模式:

CREATE TABLE `shepherd_navigation_container` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(100) NOT NULL, 
    `description` text, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB 

容器實體模型:

/** 
* @Entity 
* @Table(name="shepherd_navigation_container") 
*/ 
class Model 
{ 
    /** 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue 
    */ 
    protected $id; 

    /** 
    * @Column 
    */ 
    protected $name; 

    /** 
    * @Column(nullable=true) 
    */ 
    protected $description; 

    /** 
    * @OneToMany(targetEntity="Shepherd\Navigation\Domain\Link\Model", mappedBy="container") 
    */ 
    private $links; 

    /** 
    * Constructor 
    */ 
    public function __construct() 
    { 
     $this->links = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

    /** Accessors and Mutators excluded for brevity **/ 
} 

我缺少什麼?我究竟做錯了什麼?

+0

我不相信你需要在你的關聯映射中的目標實體的整個路徑。它看起來像一些你有整個路徑,其他人只有實體名稱。我不確定這是否是造成問題的原因,但這是你可以看到的。 – 2011-03-18 15:19:45

+0

謝謝傑里米,你是對的。我在命名模型時不一致。但問題仍然存在。 – user175590 2011-03-22 18:51:10

回答

5

我想通了(通過閱讀文檔http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/getting-started-xml-edition.html)。事實證明,實際上存在一些問題。

問題1 =>我沒有提供設置容器變量的方法。

// Inside the Link Entity class... 

public function setContainer($container) 
{ 
    $this->container = $container; 
} 

問題2 =>我沒有設置容器值。錯誤的是,我認爲Doctrine 2在內部做到了這一點,但是我發現在沖洗之前需要設置容器變量。

對我而言,這是愚蠢的疏忽。

$link = new Link(); 
$link->setContainer($container); 

// $em is the Entity Manager 
$em->persist($link); 
$em->flush(); 

問題3 =>的容器($容器)需要要麼之前沖洗或在需要改變容器實體@OneToMany定義持續存在。我選擇更新容器實體定義。看看這裏(http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-associations.html#transitive-persistence-cascade-operations)瞭解更多信息。

// Inside the Container Entity class... 
/** 
* @OneToMany(targetEntity="Shepherd\Navigation\Domain\Link\Model", mappedBy="container", cascade={"persist"}) 
*/ 

做出這些改變和刪除的鏈接實體類(原來我並不需要它)的@OneToOne節點的關係後,一切正常。我希望這可以幫助別人。