2010-07-25 42 views
9

我閱讀官方文檔和大量的線程,但仍然沒有找到我的情況的解決方案。我的情況非常基本。我有兩個實體:評論和關鍵字。一個評論可以有許多關鍵字,但每個關鍵字只能用於一個評論。關鍵字表中的關鍵字不是唯一的。所以我決定這是一對多的關係。表結構只是想如下:理解學說中關係映射的問題2

關鍵字

id   int(11) 
comment_id int(11) 
text  varchar(30) 

評論

id  int(11) 
text text 

這裏是我如何映射他們:


/** 
* @Entity 
* @Table(name="comments") 
**/ 
class Comments 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 
    /** @Column(type="text") */ 
    private $text; 

    /** 
    * @OneToMany(targetEntity="keywords", mappedBy="comment_id") 
    */ 
    private $keywords; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
    public function getKeywords(){return $this->keywords;} 
} 
/** 
* @Entity 
* @Table(name="keywords") 
*/ 

class Keywords 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 

    private $text; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
} 
 

,以及如何使用它是這樣的:


$comments = $this->em->getRepository('comments')->findAll(); 
foreach($comments as $comment){ 
    foreach($comment->getKeywords() as $keyword){ 
     $keyword->getText(); 
    } 
}

,並得到了這個錯誤:

 
Notice: Undefined index: comment_id in C:\web_includes\doctrine\ORM\Persisters\BasicEntityPersister.php on line 1096 
Notice: Trying to get property of non-object in C:\web_includes\doctrine\ORM\Persisters\BasicEntityPersister.php on line 1098 
Warning: Invalid argument supplied for foreach() in C:\web_includes\doctrine\ORM\Persisters\BasicEntityPersister.php on line 1098 
Notice: Undefined index: comment_id in C:\web_includes\doctrine\ORM\PersistentCollection.php on line 168 
Fatal error: Call to a member function setValue() on a non-object in C:\web_includes\doctrine\ORM\PersistentCollection.php on line 169 
有什麼不對?應該在哪裏定義comment_id?我的映射是否正確?我真的堅持,需要幫助,所以請任何意見非常歡迎。

+0

怎麼樣'comment_id'?你如何設置關係betn評論和關鍵字? – Sadat 2010-07-25 10:38:59

+0

comment_id是關鍵字表中數據庫中具有此關鍵字所屬註釋ID的字段。我想教條會在選擇關鍵字時使用它。 關係是這樣的 OneToMany(targetEntity =「keywords」,mappedBy =「comment_id」) 是不是正確? – SET 2010-07-25 11:03:22

回答

13

mappedBy屬性沒有提及外鍵的名稱,這就是「@JoinColumn」註釋的用途。此方案的正確的映射是:

/** 
* @Entity 
* @Table(name="comments") 
**/ 
class Comments 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 
    /** @Column(type="text") */ 
    private $text; 

    /** 
    * @OneToMany(targetEntity="keywords", mappedBy="comment") 
    */ 
    private $keywords; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
    public function getKeywords(){return $this->keywords;} 
} 

/** 
* @Entity 
* @Table(name="keywords") 
*/ 
class Keywords 
{ 
    /** @Id @Column(type="integer") */ 
    private $id; 

    /** 
    * @ManyToOne(targetEntity="Comments", inversedBy="keywords") 
    */ 
    private $comment; 

    /** 
    * @Column(type="text") */ 
    private $text; 

    public function getText(){return $this->text;} 
    public function getId(){return $this->id;} 
} 

使用Schema工具它產生相當於您的模式的SQL:

CREATE TABLE comments (id INT NOT NULL, text LONGTEXT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB; 
CREATE TABLE keywords (id INT NOT NULL, comment_id INT DEFAULT NULL, text LONGTEXT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB; 
ALTER TABLE keywords ADD FOREIGN KEY (comment_id) REFERENCES comments(id); 

兩個問題在您的映射:

  1. 你必須瞭解擁有和反面的區別。只有一對多單向關係需要第三個連接表。然而像雙向關係一樣,在我擁有的side屬性Keyword :: $ comment的映射中,它是有效的。
  2. 「mappedBy」指的是另一個targetEntity上屬於「此關聯的另一方」的屬性。 InversedBy具有相同的含義,只是在反方總是指定反方向,反方向映射。

這一切聽起來都非常複雜,但從ORM技術角度來看,它非常有效,因爲它允許使用最少數量的所需SQL UPDATE語句更新關聯。參見如何反/擁有作品的文檔:

http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en#owning-side-and-inverse-side

+0

這真的很有用!非常感謝。但我不得不問,單向關係和雙向關係有什麼區別。另外,在我的情況下,什麼實體將是反面,將擁有什麼。我想擁有和keywodrs的評論是相反的,但不能說爲什麼。 – SET 2010-07-25 23:31:50

+0

關鍵字是擁有方,因爲外鍵「comment_id」在關鍵字表上。 單向意味着您只能使用Comment :: getKeywords()從Comment評論到關鍵字。雙向意味着你可以在兩個方向上使用額外的Keyword :: getComment()(在我的例子中缺少)。 協會章節比較冗長,但您應該閱讀「協同工作」和「協會映射」章節以獲取整個概念。 – beberlei 2010-07-26 11:55:29