Reputation: 723
I have two entities, League
and Club
, and predictably a League
can have many Club
s. Just to test things out I'm trying to insert a club called test
into the league with an ID of 1 (which does exist in the database, that's not the problem). If I do the following then it works fine:
$club = new Club();
$club->setName("test");
$league = $this->getDoctrine()->getRepository("AppBundle:League")->find(1);
$club->setLeague($league);
$em->persist($club);
$em->persist($league);
$em->flush();
However, if I alter the fourth line to $league->addClub($club);
then it inserts a null value as the league_id
in the database.
I have the following code for the Club
entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Club
*
* @ORM\Table(name="club")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ClubRepository")
*/
class Club
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="League", inversedBy="clubs")
* @ORM\JoinColumn(name="league_id", referencedColumnName="id")
*/
private $league;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Club
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set league
*
* @param \AppBundle\Entity\League $league
*
* @return Club
*/
public function setLeague(\AppBundle\Entity\League $league = null)
{
$this->league = $league;
return $this;
}
/**
* Get league
*
* @return \AppBundle\Entity\League
*/
public function getLeague()
{
return $this->league;
}
}
and the following for the League
entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* League
*
* @ORM\Table(name="league")
* @ORM\Entity(repositoryClass="AppBundle\Repository\LeagueRepository")
*/
class League
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Club", mappedBy="league")
*/
private $clubs;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return League
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Constructor
*/
public function __construct()
{
$this->clubs = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add club
*
* @param \AppBundle\Entity\Club $club
*
* @return League
*/
public function addClub(\AppBundle\Entity\Club $club)
{
$this->clubs[] = $club;
return $this;
}
/**
* Remove club
*
* @param \AppBundle\Entity\Club $club
*/
public function removeClub(\AppBundle\Entity\Club $club)
{
$this->clubs->removeElement($club);
}
/**
* Get clubs
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getClubs()
{
return $this->clubs;
}
}
I've checked that the database schema is up to data with doctrine:schema:update
, and I've tried seemingly every combination of persisting and flushing... persisting the club before the league, persisting the league before the club, persisting just the league, persisting just the club, persisting the league then flushing then persisting the club then flushing again... Nothing has worked.
Upvotes: 2
Views: 2587
Reputation: 2541
Doctrine will only check the owning side of an association for changes. http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html
You can cascade changes to the owning side like this
// AppBundle\Entity\League.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* League
*
* @ORM\Table(name="league")
* @ORM\Entity(repositoryClass="AppBundle\Repository\LeagueRepository")
*/
class League
{
// ...
/**
* Add club
*
* @param \AppBundle\Entity\Club $club
*
* @return League
*/
public function addClub(\AppBundle\Entity\Club $club)
{
$this->clubs[] = $club;
$club->setLeague($this);
return $this;
}
// ...
}
Upvotes: 0
Reputation: 521
The problem comes from your addClub()
method. When you add a club in the league, you have to tell the club in which league it's being added.
Your method should look like this
public function addClub(Club $club)
{
$this-cubs[] = $club;
$club->setLeague($this); // <-- there, tell the club in which league it is
return $this;
}
Upvotes: 1