2011-03-16 6 views
5

私はZendFramework 1.11.2内のORMとしてDoctrine 2を使用する双方向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 **/ 
} 

注:上記container_id列に保護されたプロパティ$ CIDマップ。

コンテナテーブルスキーマ:

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

アソシエーションマッピングでターゲットエンティティへのパス全体が必要とは思われません。いくつかのパスのように見え、他のものにはエンティティ名だけがあります。それが問題を引き起こしているのかどうかはわかりませんが、あなたが見ることができるものです。 –

+0

ありがとう、ジェレミー、そうです。私はモデルの命名に一貫性がありません。しかし、問題は依然として続く。 – user175590

答えて

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(); 

前紅潮または変更するために必要なコンテナエンティティの@OneToMany定義に永続化することのいずれかに必要な問題点3 =>コンテナ($コンテナ)。コンテナのエンティティ定義を更新することを選択しました。詳細はこちら(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ノードの関係を(判明私はそれを必要としなかった)を除去した後、すべてがうまく働きました。私はこれが誰かを助けることを望む。

関連する問題