【问题标题】:Doctrine Table Inheritance - No identifier/primary key specified for EntityDoctrine Table Inheritance - 没有为实体指定标识符/主键
【发布时间】:2017-05-25 06:07:03
【问题描述】:

在以 Postgres 作为数据库的 Doctrine 2/Symfony 3 中,我试图创建一个包含以下字段的表:

**actions-reviews**
id
action_id
action_task_id
document_id
review_to
review_date
review_description
review_by
is_effective

该表要么链接到一个 doc_id,它是一个名为 Document 的实体的外键,或者是一个名为 ActionTask 的实体的 action_task_id。为了实现这一点,我通过使用鉴别器来使用继承映射。在 skipper 中,实体关系如下所示:

如您所见,ActionTask 和 ActionReview 都是 Action 实体的子集。

我的问题是在创建实体并运行 php bin/console dictionary:schema:update --force 时出现以下错误:

[Doctrine\ORM\Mapping\MappingException]                                      
  No identifier/primary key specified for Entity "AppBundle\Entity\ActionTask  
  Review". Every Entity must have an identifier/primary key. 

阅读论坛时,我将@ORM/Id 添加到 ActionTaskReview 实体,然后它会更新数据库而不会出现任何错误。但是,当我查看 postgres 表时,只有 document_id 字段没有 action_task_id 字段。 我做错了什么,因为当我排除 @ORM/Id 时 document_id 没有抛出同样的错误?

我的教义实体看起来像: ActionReview.php

/**
 * @ORM\Entity
 * @ORM\Table(name="actions_reviews")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="owner", type="string")
 * @ORM\DiscriminatorMap({"document":"AppBundle\Entity\DocumentActionReview","action_task":"AppBundle\Entity\ActionTaskReview"})
 * @Discriminator(field = "owner", map = {"document": "AppBundle\Entity\DocumentActionReview", "action_task": "AppBundle\Entity\ActionTaskReview"})
 */
abstract class ActionReview
{
    /**
     * @ORM\Id
     * @ORM\Column(type="guid")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     */
    private $review_date;

    /**
     * @ORM\Column(type="text", nullable=true)
     */
    private $review_description;

    /**
     * @ORM\Column(type="boolean", nullable=true)
     */
    private $is_effective;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Action", inversedBy="action_review")
     * @ORM\JoinColumn(name="action_id", referencedColumnName="id")
     */
    private $action;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Employee")
     * @ORM\JoinColumn(name="review_to", referencedColumnName="id")
     */
    private $review_to;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Employee")
     * @ORM\JoinColumn(name="review_by", referencedColumnName="id")
     */
    private $review_by;

    /**
     * Get id
     *
     * @return guid
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set reviewDate
     *
     * @param \DateTime $reviewDate
     *
     * @return ActionReview
     */
    public function setReviewDate($reviewDate)
    {
        $this->review_date = $reviewDate;

        return $this;
    }

    /**
     * Get reviewDate
     *
     * @return \DateTime
     */
    public function getReviewDate()
    {
        return $this->review_date;
    }

    /**
     * Set reviewDescription
     *
     * @param string $reviewDescription
     *
     * @return ActionReview
     */
    public function setReviewDescription($reviewDescription)
    {
        $this->review_description = $reviewDescription;

        return $this;
    }

    /**
     * Get reviewDescription
     *
     * @return string
     */
    public function getReviewDescription()
    {
        return $this->review_description;
    }

    /**
     * Set isEffective
     *
     * @param boolean $isEffective
     *
     * @return ActionReview
     */
    public function setIsEffective($isEffective)
    {
        $this->is_effective = $isEffective;

        return $this;
    }

    /**
     * Get isEffective
     *
     * @return boolean
     */
    public function getIsEffective()
    {
        return $this->is_effective;
    }

    /**
     * Set action
     *
     * @param \AppBundle\Entity\Action $action
     *
     * @return ActionReview
     */
    public function setAction(\AppBundle\Entity\Action $action = null)
    {
        $this->action = $action;

        return $this;
    }

    /**
     * Get action
     *
     * @return \AppBundle\Entity\Action
     */
    public function getAction()
    {
        return $this->action;
    }

    /**
     * Set reviewTo
     *
     * @param \AppBundle\Entity\Employee $reviewTo
     *
     * @return ActionReview
     */
    public function setReviewTo(\AppBundle\Entity\Employee $reviewTo = null)
    {
        $this->review_to = $reviewTo;

        return $this;
    }

    /**
     * Get reviewTo
     *
     * @return \AppBundle\Entity\Employee
     */
    public function getReviewTo()
    {
        return $this->review_to;
    }

    /**
     * Set reviewBy
     *
     * @param \AppBundle\Entity\Employee $reviewBy
     *
     * @return ActionReview
     */
    public function setReviewBy(\AppBundle\Entity\Employee $reviewBy = null)
    {
        $this->review_by = $reviewBy;

        return $this;
    }

    /**
     * Get reviewBy
     *
     * @return \AppBundle\Entity\Employee
     */
    public function getReviewBy()
    {
        return $this->review_by;
    }
}

ActionTaskReview.php

namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

use JMS\Serializer\Annotation\Exclude;

/**
 * ActionTaskReview
 * @ORM\Entity
 */
class ActionTaskReview
{
    /**      
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\ActionTask", inversedBy="action_review")
     * @ORM\JoinColumn(name="action_task_id", referencedColumnName="id") \AppBundle\Entity\ActionTask
     */
    private $action_task;


    /**
     * Set actionTask
     *
     * @param \AppBundle\Entity\ActionTask $actionTask
     *
     * @return ActionTaskReview
     */
    public function setActionTask(\AppBundle\Entity\ActionTask $actionTask = null)
    {
        $this->action_task = $actionTask;

        return $this;
    }

    /**
     * Get actionTask
     *
     * @return \AppBundle\Entity\ActionTask
     */
    public function getActionTask()
    {
        return $this->action_task;
    }
}

DocumentActionReview.php

<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Entity
 * @ORM\Table(name="documents_actions_reviews")
 */
class DocumentActionReview extends \AppBundle\Entity\ActionReview
{
    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Document", inversedBy="action_review")
     * @ORM\JoinColumn(name="document_id", referencedColumnName="id")
     */
    private $document;
    /**
     * Set document
     *
     * @param \AppBundle\Entity\Document $document
     *
     * @return DocumentActionReview
     */
    public function setDocument(\AppBundle\Entity\Document $document = null)
    {
        $this->document = $document;
        return $this;
    }
    /**
     * Get document
     *
     * @return \AppBundle\Entity\Document
     */
    public function getDocument()
    {
        return $this->document;
    }
}

【问题讨论】:

    标签: postgresql symfony doctrine-orm


    【解决方案1】:

    首先,您的ActionTaskReview 应该扩展ActionReview

    namespace AppBundle\Entity;
    use Doctrine\ORM\Mapping as ORM;
    
    use JMS\Serializer\Annotation\Exclude;
    
    /**
     * ActionTaskReview
     * @ORM\Entity
     */
    class ActionTaskReview extends ActionReview
    {
    ...
    }
    

    我不确定您想要实现什么,因为您使用的是Single Table Inheritance,但在 DocumentActionReview 类上设置了@ORM\Table(name="documents_actions_reviews") 注释。如果您需要为继承的实体创建自己的表,请切换到 Class Table Inheritance 或删除注释。

    【讨论】:

    • 谢谢我错过了扩展 ActionReview!
    【解决方案2】:

    每个实体类都必须有一个标识符/主键。您可以使用@Id 注解选择用作标识符的字段。

    `/**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @GeneratedValue
     */
    private $id;`
    

    【讨论】:

      猜你喜欢
      • 2013-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-06
      • 1970-01-01
      • 2015-07-25
      • 2016-01-31
      • 2018-08-13
      相关资源
      最近更新 更多