Skip to content

Loading…

DDC-3169: ManyToMany association fails when joining on a single column of a composity key #3949

Open
doctrinebot opened this Issue · 0 comments

2 participants

@doctrinebot

Jira issue originally created by user bramstroker:

I have two entities with a ManyToMany association between them. The first entity Campsite* has a composite key (campsiteID, year). The second entity Region has a single key (*regionID).
I want to create an association between Campsite::campsiteID* and *Region::regionID. See the entities below.

/****
 * @ORM\Table(name="Campsite")
 */
class Campsite
{
    /****
     * @ORM\Id
     * @ORM\Column(name="campsiteID", type="integer", precision=0, nullable=false)
     */
    protected $campsiteID;

    /****
     * @ORM\Id
     * @ORM\Column(name="year", type="smallint", precision=0, nullable=false)
     */
    protected $year;

    /****
     * @ORM\ManyToMany(targetEntity="AcsiGeo\Entity\Region", fetch="EAGER", cascade={"detach"})
     * @ORM\JoinTable(name="CampsiteRegion",
     *   joinColumns={
     *     @ORM\JoinColumn(name="campsiteID", referencedColumnName="campsiteID", nullable=false)
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="regionID", referencedColumnName="regionID", nullable=false)
     *   }
     * )
     * @var \Doctrine\Common\Collections\ArrayCollection $regions
     */
    protected $regions;
}
/****
 * @ORM\Table(name="Region")
 */
class Region
{
    /****
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(name="regionID", type="integer", precision=0, nullable=false)
     */
    protected $regionID;
}

I run the following code to persist a new one.

$campsite = new Campsite();
$campsite->setCampsiteID(111111);
$campsite->setYear(2014);

$region = new Region();
$region->setRegionID(1);
$campsite->addRegion($region);

$em->persist($region);
$em->persist($campsite);
$em->flush();

This results in a record added to the CampsiteRegion table:

campsiteID : 2014
regionID: 1

This is clearly wrong as the value of the year field is added to the campsiteID column.

While debugging the problem I've found an issue with the method to determine the params in ManyToManyPersister on line 147.
The following code pops the last identifier from the array of identifiers.

$params[] = $isRelationToSource ? array*pop($identifier1) : array*pop($identifier2);

In my case:

array(
    'campsiteID' => 111111,
    'year' => 2014
)

Which picks 2014 as the value to use.
When I change the code to get the actual column from the array everything works as expected.

$params[] = $isRelationToSource ? $identifier1[$joinTableColumn] : $identifier2[$joinTableColumn];

I am not 100% sure if this change will have some side effects / edge case I'm not aware of.

For the time being I have fixed the problem bij just reversing the properties in my class, but this is not a real fix of course.

@beberlei beberlei was assigned by doctrinebot
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.