<?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;
}
}
和
<?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属性吗?如果我在两个不同的类上使用单表继承,我就无法手动得到这一点。
我做错了什么吗?我找不到任何关于这种实现的有价值的信息。
thnak你。
CommentVote正在扩展Vote。作为resource_type投票。所以现在你必须为CommentVote设置它,它不能为null:
resource_type VARCHAR(255) NOT NULL
你必须说明你想要的resource_type是什么。我猜不出来。
你可以在投票中设置为空:
/**
* @Column(type="string", length=255", nullable=true)
*/
private $resource_type;
或者您可以为resource_type设置一个默认值。如果是这样,您可以选择在CommentVote的__construct中设置默认值,或者您也可以在@PreUpdate方法中设置该值。
我有一个类似的问题,但那是因为我这样做:
<?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();
在我的情况下,问题与Doctrine无关:因为self
不使用延迟绑定,我不知不觉地得到了BaseClass
而不是SubclassOne
的实例。由于BaseClass
没有鉴别符映射,所以判别符列不能被Doctrine填充。
我已经摆脱了所有的::create()
的废话,并开始使用常规的构造函数,我可能也会使BaseClass
抽象。