2011-04-29 47 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抽象。