How to deal with association on composite key entities with Doctrine2?

Viewed 13726

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 name id 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?

2 Answers

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.

Related