Symfony/Doctrine在多对一关系中插入空作为外键


Symfony/Doctrine inserts null as foreign key in many to one relationship

我有两个实体,LeagueClub,并且可以预见,一个League可以有多个Club。只是为了测试的东西出来,我试图插入一个名为test的俱乐部与ID为1的联赛(这确实存在于数据库中,这不是问题)。如果我执行以下操作,那么它可以正常工作:

$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();

但是,如果我将第四行更改为$league->addClub($club);,那么它将在数据库中插入一个空值作为league_id

我有以下Club实体代码:

<?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;
    }
}

和以下League实体:

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;
    }
}

我已经检查了数据库模式是否符合doctrine:schema:update的数据,并且我已经尝试了持久化和刷新的每种组合…在联赛之前坚持俱乐部,在俱乐部之前坚持联赛,只坚持联赛,只坚持俱乐部,坚持联赛然后冲洗然后坚持俱乐部,然后再次冲洗……

问题来自您的addClub()方法。当你在联赛中添加一个俱乐部时,你必须告诉该俱乐部它将被添加到哪个联赛。

你的方法应该是这样的

public function addClub(Club $club)
{
    $this-cubs[] = $club;
    $club->setLeague($this); // <-- there, tell the club in which league it is
    return $this;
}

Doctrine将只检查关联的所有者方是否有更改。http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

你可以像这样级联到所有者端

// 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;
    }
    // ...
}