Say I have an Offer, which can have 1-n Range. Immediately you think, "put a offer_id inside Range".
But my Offer has a composite primary key (composed of two fields). There is no AUTOINCREMENT id column.
The Doctrine2 documentation doesn't say much about that particular case, here is my entities:
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table()
* @ORM\Entity
*/
class Offer
{
/**
* @var Site $site
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Site")
* @ORM\JoinColumn(name="site_id", referencedColumnName="id")
*/
private $site;
/**
* @var string $pouet
* @ORM\Id
* @ORM\Column(name="pouet", type="string", length=255)
*/
private $pouet;
}
<?php
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="RangeItem")
* @ORM\Entity
*/
class Range
{
/**
* @todo This is test code only do not push me :-)
* @var ArrayCollection
* @ORM\ManyToOne(targetEntity="Offer")
*/
private $offers;
}
I obtaind this error:
[Doctrine\ORM\ORMException]
Column nameid
referenced for relation from Pouet\MyBundle\Entity\Range towards Pouet\MyBundle\Entity\Offer does not exist.
That make sense, but how can I deal with this issue? Is a Table with composite primary key forbidden to have associations on it?
I believe the solution is to mirror the primary key (PK) for the foreign key (FK). I.E. for each column that makes up the PK (site, pouet) you need to have the same columns on the related entity.
You can do this by using the JoinColumns
annotation (or the equivalent in YAML/XML) with a JoinColumn
for each part of the composite FK:
/**
* @ORM\Table(name="RangeItem")
* @ORM\Entity
*/
class Range
{
/**
* @todo This is test code only do not push me :-)
* @var ArrayCollection
* @ORM\ManyToOne(targetEntity="Offer")
* @ORM\JoinColumns(
* @ORM\JoinColumn(name="site_id", referencedColumnName="site_id"),
* @ORM\JoinColumn(name="pouet", referencedColumnName="pouet")
* )
*/
private $offers;
}
I hope this might help somebody who is still struggling with this issue.
You should be able to use a @JoinColumn
annotation in the Range
class to specify which Id to use:
/**
* @ORM\ManyToOne(targetEntity="Offer")
* @ORM\JoinColumn(name="offer_pouet", referencedColumnName="pouet")
*/
private $offers;
Because the defaults for @JoinColumn
, if you do not specify them, would be offer_id
and id
, respectively, you need to manually specify (I'm making a bit of an assumption here that pouet
is a unique value for your Offer
class).
EDIT: based on your comment, I found a tutorial on the Doctrine Project site for Composite Primary Key. The entity relationship has mappedBy
for one key and indexBy
for the other. Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With