Помогите мне понять наследование одного класса в Учении 2 - PullRequest
1 голос
/ 29 апреля 2011
<?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, используемое в качестве дискриминатора?Я не понимаю этого вручную, если использую Single Table Inheritance для двух разных классов.

Если я что-то не так делаю, я не смог найти никакой ценной информации об этом виде реализации.

спасибо.

Ответы [ 2 ]

0 голосов
/ 11 августа 2012

У меня была похожая проблема, но это потому, что я делал это:

<?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 также абстрактным.

0 голосов
/ 29 апреля 2011

CommentVote расширяет Голосование. Голосовать как тип_ресурса. Так что теперь вы должны установить его для CommentVote, и он не может быть нулевым:

resource_type VARCHAR(255) NOT NULL

Вы должны сказать, что вы хотите, чтобы resource_type был. Я не могу догадаться, что.

Однако вы можете установить это значение в Голосование:

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

или вы можете установить значение по умолчанию для resource_type. Если это так, вы можете установить значение по умолчанию в __construct of CommentVote или установить значение в методе @PreUpdate.

...