StrikeForceZero
StrikeForceZero

Reputation: 2379

Doctrine - Symfony2 | Many to Many targeting the same entity

I am trying to create a many-to-many foreign key table relation targeting the same entity.

I have successfully created relations with other entities but I'm having trouble when targeting the same entity.

I read a few stack overflow questions and answers and saw what I was doing was possible.. I based my class of this example - the table unit_relations is empty when i add a parent, but works when I add a child to a unit. I'm assuming because the field has the inversedBy annotation.

What do I need to add to allow bi-drectional updating/inserting?

I tried swapping the joinColums like this answer - nothing...

--

 /**
 * Unit
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Acme\DemoBundle\Entity\UnitRepository")
 */
class Unit
{
   ....

   /**
     * @ORM\ManyToMany(targetEntity="Unit",  inversedBy="parents")
     * @ORM\JoinTable(name="unit_relations",
     *     joinColumns={@ORM\JoinColumn(name="unit_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="child_unit_id", referencedColumnName="id")}
     * )
     */
    private $children;

    /**
     * @ORM\ManyToMany(targetEntity="Unit",  mappedBy="children")
     */
    private $parents;
}

is adding inversedBy instead of having mappedBy, with the join columns also swapped, the proper way to do it?

Can someone explain this?

/**
     * @ORM\ManyToMany(targetEntity="Unit",  inversedBy="parents")
     * @ORM\JoinTable(name="unit_relations",
     *     joinColumns={@ORM\JoinColumn(name="unit_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="child_unit_id", referencedColumnName="id")}
     * )
     */
    private $children;

    /**
     * @ORM\ManyToMany(targetEntity="Unit",  inversedBy="children")
     * @ORM\JoinTable(name="unit_relations",
     *     joinColumns={@ORM\JoinColumn(name="child_unit_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="unit_id", referencedColumnName="id")}
     * )
     */
    private $parents;

EDIT

as requested here's the code showing how I create the relation. I just realized it may because the entity doesn't have an id yet since I'm adding the relation on its creation...

$unit = new \Acme\DemoBundle\Entity\Unit();
/* @var $parentUnit \Acme\DemoBundle\Entity\Unit */
$parentUnit = $this->getDoctrine()->getRepository('AcmeDemoBundle:Unit')->findById($request->get('unitId'));
$unit->addParent($parentUnit);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($unit);
$entityManager->flush();

Upvotes: 1

Views: 3468

Answers (1)

tjoussen
tjoussen

Reputation: 61

It doesn't matter, that there is no ID, when you add a parent relations.

I cant in detail explain why this happens, but i think the main problem is, that in Many-To-Many Self-Referencing the attribute with JoinTable annotation is potentially the Master-Entity. You can say, that it "holds" all other relations to this Entity.

You can recieve the bi-directional updating/inserting while changing the function $unit->addParent($parent). Change it as follows:

  public function addParent($parent)
  {
      $this->parents[] = $parent;
      $parent->addChild($this); // Add the relation in the proper way
  }

That should work fine!

Regards!

Upvotes: 1

Related Questions