tvanc
tvanc

Reputation: 4324

Doctrine ORM: Populate join column of related entities on persist

Given the below simple entities in Doctrine ORM, is there a simple way to create a Parent object, add Children to it, and then persist the Parent and its children in one call to EntityManager#persist() and EntityManager#flush()?

Currently, I'm persisting Parent, flushing the entity manager, then adding Parent to each Child, persisting each Child and then flushing the entity manager again. Otherwise, each Child is persisted to the database, but the join column is null. I tried a lifecycle callback on Parent, but postPersist() is called after all entities are persisted, not right after the parent entity and before the children are persisted.

class Parent {
  /**
   * @ORM\Id
   * @ORM\Column(type="integer")
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  protected $id;

  /**
   * @ORM\OneToMany(
   *    targetEntity="Child",
   *    mappedBy="parent",
   *    cascade={"persist", "merge", "remove"}
   * )
   */
  protected $children;

  public function __construct () {
    $this->children = new ArrayCollection;
  }

  public function addChild (Child $child) {
    $this->children[] = $child
  }
}

class Child {
  /**
   * @ORM\Id
   * @ORM\Column(type="integer")
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  protected $id;

  /**
   * @ORM\ManyToOne(
   *    targetEntity="Parent",
   *    inversedBy="children",
   * )
   */
  protected $parent;
}

Upvotes: 0

Views: 1674

Answers (2)

Carlos Perez Perez
Carlos Perez Perez

Reputation: 407

every time you use manytoone or onetomany relations, use php app/console doctrine:generate:entities in the console, so it will autocreate the functions addChild and removeChild. This way you dont need to create them manually

Upvotes: 0

FyodorX
FyodorX

Reputation: 1480

You don't have to persist the children manually. That's what cascade={"persist"} is for.

Try this in Parent's addChild():

public function addChild (Child $child) {
    $this->children[] = $child;
    $child->setParent($this);
}

Now you can persist and flush only the parent and its children will be persisted too.

Upvotes: 0

Related Questions