Home » Php » php – Doctrine 2 mapping referencing unique key

php – Doctrine 2 mapping referencing unique key

Posted by: admin July 12, 2020 Leave a comment

Questions:

Basic question:

Is it possible to map an association using Doctrine referencing not a primary but only a unique key?

Extended Version:

I have an Entity (Participation) which may reference 2 other entities (DropoutCause and DischargeType). Depending on this combination some other attributes are implied, based on another (4th) table (DropoutScenario) in database. Because either of both referenced entities may be null I couldn’t declare them as primary but only unique key in the 4th table.

The problem is I only get an error when I try to map this with Doctrine:

Missing value for primary key id on
Application\Entity\Trainings\DropoutScenario

Am I doing something wrong, or is this simply not possible with Doctrine?
If not, is there any better solution how I could do this?

I’ve been searching for quite a long time now and dug the Doctrine documentation but I simply couldn’t find anything on this…

Stripped code samples of my mappings are below.

Participation:

<?php

namespace Application\Entity\Trainings;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\MappedSuperclass
 */
abstract class Participation {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Application\Entity\DropoutCause")
     * @ORM\JoinColumn(name="dropout_cause_id", referencedColumnName="id"))
     */
    protected $dropoutCause;

    /**
     * @ORM\ManyToOne(targetEntity="Application\Entity\DischargeType")
     * @ORM\JoinColumn(name="discharge_id", referencedColumnName="id"))
     */
    protected $dischargeType;

    /**
     * @ORM\ManyToOne(targetEntity="DropoutScenario")
     * @ORM\JoinColumns({
     * @ORM\JoinColumn(name="discharge_id", referencedColumnName="discharge_id"),
     * @ORM\JoinColumn(name="dropout_cause_id", referencedColumnName="dropout_cause_id")
     * })
     */
    private $scenario;

DropoutScenario:

<?php

namespace Application\Entity\Trainings;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="training_dropout_scenarios")
 */
class DropoutScenario {

    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Application\Entity\DropoutCause")
     * @ORM\JoinColumn(name="dropout_cause_id", referencedColumnName="id"))
     */
    protected $dropoutCause;

    /**
     * @ORM\ManyToOne(targetEntity="Application\Entity\DischargeType")
     * @ORM\JoinColumn(name="discharge_id", referencedColumnName="id"))
     */
    protected $dischargeType;

    /** @ORM\Column(type="integer", name="dropout_cause_id") */
    protected $dropoutCauseId;

    /** @ORM\Column(type="integer", name="discharge_id") */
    protected $dischargeTypeId;
How to&Answers:

Since I did not get any answer yet I did another research today and I found the answer to my own question through the Doctrine mailing lists forum.
Seems like I just searched for the wrong keywords…

Doctrine 2 unfortunately does not support it. What a pity! 🙁

From the Doctrine documentation:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/limitations-and-known-issues.html#join-columns-with-non-primary-keys

It is not possible to use join columns pointing to non-primary keys.
Doctrine will think these are the primary keys and create lazy-loading
proxies with the data, which can lead to unexpected results. Doctrine
can for performance reasons not validate the correctness of this
settings at runtime but only through the Validate Schema command.

Similar question:
Is it possible to reference a column other than 'id' for a JoinColumn?

Answer:

Just like following references, Doctrine does not support this type of mapping

http://www.doctrine-project.org/jira/browse/DDC-1269

http://www.doctrine-project.org/jira/browse/DDC-1114

I think it will be helps to you.