I'm trying to handle a legacy database with doctrine. There is many fields in different tables that are codes which refer to a unique code table CHOIXCOD. This table relies on two keys. The key (CC_CODE) that corresponds to the value in the linked fields, and a type code (CC_TYPE) identifying which field the first key is targeting.
So i used Doctrine Inheritance on an abstract entity targeting this code table, and created as many children entities as there is difference types. What i understand is that Doctrine will make snippets of CHOIXCOD on the CC_TYPE field, and in each snippet, CC_CODE will be the key column.
But, when all $ccCode are differents all works fine, but, in one table having multiple references to CHOIXCOD, if two fields referencing CC_CODE have the same value, Doctrine will give them the same CC_TYPE value, resulting in targeting the wrong entity, crash, 500 error, project being late, me being fired.
So here is the mother entity.
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="CHOIXCOD")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="CC_TYPE", type="string", length=3)
* @ORM\DiscriminatorMap({"PHV" = "Phasevocale",
* "TMS" = "Typemessage",
* "PRI" = "Priorite",
* "ZEL" = "Etatlivraison",
* "ZEM" = "Etatmessage",
* "ZOR" = "Originems"})
*/
abstract class Choixcod
{
/**
* @var string|null
*
* @ORM\Column(name="CC_CODE", type="string", length=3, nullable=true)
* @ORM\Id
*/
protected $ccCode;
/**
* @var string|null
*
* @ORM\Column(name="CC_LIBELLE", type="string", length=105, nullable=true)
*/
protected $ccLibelle;
/**
* @var string|null
*
* @ORM\Column(name="CC_ABREGE", type="string", length=17, nullable=true)
*/
protected $ccAbrege;
/**
* @var string|null
*
* @ORM\Column(name="CC_LIBRE", type="string", length=70, nullable=true)
*/
protected $ccLibre;
And all the children are like this
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Etatmessage extends Choixcod{}
They are then used in other entities following a ManyToOne relation
/**
*
* @ORM\ManyToOne(targetEntity="Etatmessage")
* @ORM\JoinColumn(name="ZMS_ETATMESSAGE", referencedColumnName="CC_CODE")
* @ToNull(primaryKey="ccCode")
*/
private $zmsEtatmessage;
The @ToNull annotation is one we wrote to handle the empty or full of spaces foreign keys). I tried to removed them, that doesn't change anything.
Any idea welcome.
Ok, so after struggling with that problem for a while, I understood that Doctrine stores a two dimensions array in order to request joins (1-entity joined, 2-id of entity instance). I suppose the aim is to limit the number of request done for a yet known instance.
In our case, inheritance, the first dimension of the array is named with the extended entity so as I had the same ids for the same first dimension name that was messed up from the beginning. Setting the discriminator as @Id
could have solved this problem but Doctrine does not automatically set the discriminator value in object, throwing an id missing exception.
So the solution I kept is to put an annotation on foreign key that specifies discriminator value this foreign key corresponds to. When encountered in doctrine postLoad
event, I request the database on foreign key value (the primary key corresponding being CC_CODE
) and discriminator (the value of CC_TYPE
) in annotation, and put it into an another field.