Parent Child Relationship With A Single Entity In Doctrine 2
17,960
This should work:
<?php
use Doctrine\Common\Collections\ArrayCollection;
/** @ORM\Entity */
class Category {
/**
* @ORM\Id
* @ORM\Column(type="integer", name="id")
* @ORM\GeneratedValue
*/
protected $id;
// ...
/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
*/
protected $children;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* @ORM\JoinColumn(name="parent", referencedColumnName="id")
*/
protected $parent;
public function __construct() {
$this->children = new ArrayCollection();
}
// Once you have that, accessing the parent and children should be straight forward
// (they will be lazy-loaded in this example as soon as you try to access them). IE:
public function getParent() {
return $this->parent;
}
public function getChildren() {
return $this->children;
}
// ...
// always use this to setup a new parent/child relationship
public function addChild(Category $child) {
$this->children[] = $child;
$child->setParent($this);
}
public function setParent(Category $parent) {
$this->parent = $parent;
}
}
Author by
HenryHayes
Updated on June 23, 2022Comments
-
HenryHayes almost 2 years
I have database table that looks like this:
+----+--------+--------------------+ | id | parent | description | +----+--------+--------------------+ | 1 | null | P Cat 1 | | 2 | 1 | Child 1 of P Cat 1 | | 3 | 1 | Child 2 of P Cat 1 | | 4 | null | P Cat 2 | | 5 | 4 | Child 1 of P Cat 2 | | 6 | 4 | Child 2 of P Cat 2 | +----+--------+--------------------+
How can I create a doctrine 2 entity that has these columns, but I need the parent column to reference the "id" column as a parent. Of course, a parent record has a null "parent" column value.
So fair I have
<?php namespace MyNamespace; use Doctrine\ORM\Mapping AS ORM; use Doctrine\Common\Collections\ArrayCollection; /** * @ORM\Entity * @ORM\Table(name="category") **/ class Category { /** * @ORM\Id * @ORM\Column(type="integer", name="id") * @ORM\GeneratedValue */ protected $id; /** * Creates a parent / child relationship on this entity. * * @ORM\ManyToOne(targetEntity="MyNamespace\Category",inversedBy="id") * @ORM\JoinColumn(name="FK_parent_id", referencedColumnName="id", nullable=true) */ protected $parent = null; /** * @ORM\Column(type="string", name="description", length=250) * * @var string */ protected $description; /** * Gets the Primary key value. * * @return integer */ public function getId() { return $this->id; } /** * Sets another category ID as the parent of this category. */ public function setParent(Category $category) { $this->parent = $category; } /** * Clears the parent id and makes it null. */ public function clearParent() { $this->parent = null; } /** * Sets the description. * * @param string $description * @return Category */ public function setDescription($description) { $this->description = $description; return $this; } /** * Gets the description value. * * @return string */ public function getDescription() { return $this->description; } }
Needless to say, this doesn't appear to work. The questions are:
- The setParent() method doesn't appear to work as expected when another entity is added as a parent.
- I need a getChildren() method on this entity. How can I achieve that?
-
Marcelo Aymone over 7 yearsIn this case referencedColumnName="id" dont need to be changed to referencedColumnName="children"? Who are id field?
-
redreinard over 7 years@MarceloAymone The id and other fields are posted in the question, I didn't copy&paste them here, but yes, referencedColumnName="id" is correct.
-
Mentos93 about 6 yearsBut what if the child has two (or more) parents? For example a real world scenario; mom and dad? Then it would become ManyToMany on the same properties/same config, wouldn't it?
-
redreinard about 6 yearsYou would need a separate table to manage that relationship in that case, which would quite significantly change this example. But yes, you could then represent that as a ManyToMany relationship.
-
commonpike over 4 yearsSince the 'child' is the owning side of the relation, should the symmetry not be handled by
setParent()
instead of byaddChild()
? It probably both works .. -
redreinard over 4 yearsConceptually only the parent has (should have) access to the
children[]
array, so ultimately, adding to thechildren[]
array has to be done by the parent. The children array available insetParent()
represents the children of that child, not what you want to modify. There's probably ways to hack it to make it work, but I'd stick with always adding entities from the "one" side of the "one-to-many" relationship.