0
votes

In Doctrine 2/Symfony 3 with Postgres as the database I am trying to create a table with following fields:

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

The table is either linked to a doc_id which is foreign key for an entity called Document or action_task_id for entity called ActionTask. In order to achieve this I am using inheritance mapping via the use of discriminator. In skipper the entity relationship look like this: Skipper Relationship

As you can see both the ActionTask and ActionReview are sub-set of Action entity.

My issue is when create the entities and run php bin/console doctrine:schema:update --force I get the following error:

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

Reading the forums I add @ORM/Id to ActionTaskReview entity and then it updates the DB without any errors. However when I look at the postgres table only the document_id field is there not the action_task_id field. What I am doing wrong as the document_id does not throw the same error when I exclude @ORM/Id?

My Doctrine entities look like: 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;
    }
}
2

2 Answers

1
votes

First of all, your ActionTaskReview should extend ActionReview:

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

use JMS\Serializer\Annotation\Exclude;

/**
 * ActionTaskReview
 * @ORM\Entity
 */
class ActionTaskReview extends ActionReview
{
...
}

Than I am not sure what you want to achieve, as you are using Single Table Inheritance but are setting the @ORM\Table(name="documents_actions_reviews") annotation on the DocumentActionReview class. Either switch to Class Table Inheritance if you need own tables for your inherited entities or remove the annotation.

-1
votes

Every entity class must have an identifier/primary key. You can select the field that serves as the identifier with the @Id annotation.

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