2011-04-29 50 views
1
<?php 
namespace Jo\Model; 

/** 
* @Entity 
* @InheritanceType("SINGLE_TABLE") 
* @DiscriminatorColumn(name="resource_type", type="string") 
* @DiscriminatorMap({"article" = "\Jo\Model\Article\ArticleVote", "comment" = "\Jo\Model\Article\CommentVote"}) 
*/ 
class Vote 
{ 
    /** 
    * @Id 
    * @Column(type="integer") 
    * @GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ManyToOne(targetEntity="\Jo\Model\User\User") 
    */ 
    protected $user; 


    /** 
    * @Column(type="integer") 
    */ 
    protected $weight; 

    public function setWeight($weight) 
    { 
     $this->weight = $weight; 

     return $this; 
    } 

    public function getWeight() 
    { 
     return $this->weight; 
    } 
} 

而且幫助我理解單類繼承的原則2

<?php 
namespace Jo\Model\Article; 
use Jo\Model; 
/** 
* @Entity 
*/ 

class CommentVote extends Model\Vote 
{ 
    /** 
    * @ManyToOne(targetEntity="Comment") 
    */ 
    protected $comment; 

    public function setComment(Comment $comment) 
    { 
     $this->comment = $comment; 

     return $this; 
    } 

    public function getComment() 
    { 
     return $this->comment; 
    } 
} 

生成下面的表模式:

CREATE TABLE Vote (
    id INT AUTO_INCREMENT NOT NULL, 
    user_id INT DEFAULT NULL, 
    article_id INT DEFAULT NULL, 
    comment_id INT DEFAULT NULL, 
    weight INT NOT NULL, 
    resource_type VARCHAR(255) NOT NULL, 
INDEX IDX_FA222A5AA76ED395 (user_id), 
INDEX IDX_FA222A5A62922701 (article_id), 
INDEX IDX_FA222A5AF8697D13 (comment_id), 
PRIMARY KEY(id) 
) ENGINE = InnoDB; 

這看起來是正確的。

然而,當我這樣做:

$commentVote = new CommentVote(); 
$commentVote->setComment($comment); // $comment instance of Comment 
$commentVote->setWeight(1); 
$em->persist($commentVote); 
$em->flush(); 

我得到以下錯誤:

Message: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'resource_type' cannot be null 

我必須手動設置作爲鑑別的RESOURCE_TYPE財產?如果我在兩個不同的類上使用Single Table Inheritance,我不會手動指出這一點。

我做錯了什麼,我找不到有關這種實現的任何有價值的信息。

thnak you。

回答

0

評論投票正在擴大投票。投票爲resource_type。所以現在你必須將它設置爲CommentVote,並且它不能爲空:

resource_type VARCHAR(255) NOT NULL 

你必須說你想要resource_type是什麼。我無法猜測。

但是,您可以設置爲空的在投票:

/** 
* @Column(type="string", length=255", nullable=true) 
*/ 
private $resource_type; 

,或者你可以設置RESOURCE_TYPE的默認值。如果是這樣,您可以選擇在CommentVote的__construct中設置默認值,或者也可以在@PreUpdate方法中設置該值。

+0

這對我不起作用。當我這樣做的時候,Doctrine告訴我「resource_type」字段已經定義了兩次(一次作爲descriminator列,一次作爲常規列)。 – 2012-08-10 22:38:43

0

我也有類似的問題,但那是因爲我這樣做:

<?php 

/** 
* This class, although not abstract, is not intended to be instantiated, 
* and so is not in the discriminator map. 
*/ 
class BaseClass 
{ 
    public static function create() 
    { 
      return new self(); 
    } 
} 

/** 
* This class is in the discriminator map. 
*/ 
class SubclassOne 
extends BaseClass 
{ 
    // ... 
} 

$one = SubclassOne::create(); 
$em->persist($one); 
$em->flush(); 

在我的情況的問題無關,與學說:因爲self不使用後期綁定,我在不知不覺中得到一個BaseClass的實例而不是SubclassOne。由於BaseClass沒有鑑別器映射,所以鑑別器列不能被Doctrine填充。

我已經擺脫了所有的::create()胡說八道,並開始使用常規的構造函數,我也可能使BaseClass抽象。