Uploaded image for project: 'Doctrine 2 - ORM'
  1. Doctrine 2 - ORM
  2. DDC-3169

ManyToMany association fails when joining on a single column of a composity key


    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 2.4.2
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All


      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();
      $region = new Region();

      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:

          '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.


        There are no comments yet on this issue.


          • Assignee:
            beberlei Benjamin Eberlei
            bramstroker Bram Gerritsen
          • Votes:
            0 Vote for this issue
            1 Start watching this issue


            • Created: