Doctrine orm 原则2中的多个关联中未更新联接表

Doctrine orm 原则2中的多个关联中未更新联接表,doctrine-orm,Doctrine Orm,我有两个实体Slaplans和Slaholidays以及一个联接表Slaplans\u Slaholidays。 在创建了两个slaviedays对象之后,我将它们都持久化,并将它们添加到slaplan和flush中。问题是只有slaplan和slapholidays表被更新,而join表没有更新 Slaplans实体: 保存实体的代码: $allholidays=array(); $holiday=$this->_em->getRepository('ZC\Entity\Slaho

我有两个实体Slaplans和Slaholidays以及一个联接表Slaplans\u Slaholidays。 在创建了两个slaviedays对象之后,我将它们都持久化,并将它们添加到slaplan和flush中。问题是只有slaplan和slapholidays表被更新,而join表没有更新

Slaplans实体:

保存实体的代码:

$allholidays=array();
$holiday=$this->_em->getRepository('ZC\Entity\Slaholidays')->find($value);
$holiday=new ZC\Entity\Slaholidays();
//..sets holiday fields here
$this->_em->persist($holiday);
$allholidays[]=$holiday;

$slaplan->setHolidays($allholidays);
foreach ($slaplan->getHolidays() as $value) {
    $this->_em->persist($value);
}
$this->_em->persist($slaplan);
$this->_em->flush();

代码中有两个问题:

第一个:你坚持每个假期两次:第一次与

$this->_em->persist($holiday);
其次是

foreach ($slaplan->getHolidays() as $value) {
    $this->_em->persist($value);
}
实际上没有问题,因为在调用flush之前,它们实际上不会一直存在于数据库中,但是无论如何,您不需要foreach

联接表未更新的原因在$slaplan->setHolidays方法中。您正在使用正确的ArrayCollection初始化$slaplan->holidays,而在setHolidays中,您将其设置为输入参数$allholidays数组,这是错误的

所以,正确的方法是使用ArrayCollection的方法


尽管条令检查关联的拥有方是否有需要持久化的内容,但保持关联双方的同步始终很重要

我的建议是在两侧都有get、add和remove非set方法,如下所示:

class Slaplans
{
    public function getHolidays()
    {
        return $this->holidays->toArray();
    }

    public function addHoliday(Slaholiday $holiday)
    {
        if (!$this->holidays->contains($holiday)) {
            $this->holidays->add($holiday);
            $holiday->addPlan($this);
        }
        return $this;
    }

    public function removeHoliday(Slaholiday $holiday)
    {
        if ($this->holidays->contains($holiday)) {
            $this->holidays->removeElement($holiday);
            $holiday->removePlan($this);
        }
        return $this;
    }
}
$plan = $em->find('Slaplan', 1);

$holiday = new Slaholiday();
// set data on $holiday
// no need to persist $holiday, because you have a cascade={"ALL"} all on the association

$plan->addHoliday($holiday);
// no need to persist $plan, because it's managed by the entitymanager (unless you don't use change tracking policy "DEFERRED_IMPLICIT" (which is used by default))
$em->flush();
在斯拉普兰也一样

现在,当您向Slaplan添加SlapHoliday时,该Slaplan也将自动添加到SlapHoliday。移除也一样

现在你可以这样做:

class Slaplans
{
    public function getHolidays()
    {
        return $this->holidays->toArray();
    }

    public function addHoliday(Slaholiday $holiday)
    {
        if (!$this->holidays->contains($holiday)) {
            $this->holidays->add($holiday);
            $holiday->addPlan($this);
        }
        return $this;
    }

    public function removeHoliday(Slaholiday $holiday)
    {
        if ($this->holidays->contains($holiday)) {
            $this->holidays->removeElement($holiday);
            $holiday->removePlan($this);
        }
        return $this;
    }
}
$plan = $em->find('Slaplan', 1);

$holiday = new Slaholiday();
// set data on $holiday
// no need to persist $holiday, because you have a cascade={"ALL"} all on the association

$plan->addHoliday($holiday);
// no need to persist $plan, because it's managed by the entitymanager (unless you don't use change tracking policy "DEFERRED_IMPLICIT" (which is used by default))
$em->flush();

注意:不要在关联的两边都使用级联。这将使事情变得比必要的慢,并且在某些情况下会导致错误。如果您先创建Slaplan,然后将Slaplan添加到其中,则将级联保留在Slaplan中,并将其从Slaplan中删除。

发布超出必要的内容要比发布少于必要的内容好,但90%的实体声明是无用的,并且使问题难以阅读和回答。我已经删除了不相关的数据,如果您需要,可以在编辑历史记录中查看。您找到解决方案了吗?我也遇到了这个奇怪的问题。@JOHN我更改了代码,但仍然一无所获,连接表还没有更新。
class Slaplans
{
    public function getHolidays()
    {
        return $this->holidays->toArray();
    }

    public function addHoliday(Slaholiday $holiday)
    {
        if (!$this->holidays->contains($holiday)) {
            $this->holidays->add($holiday);
            $holiday->addPlan($this);
        }
        return $this;
    }

    public function removeHoliday(Slaholiday $holiday)
    {
        if ($this->holidays->contains($holiday)) {
            $this->holidays->removeElement($holiday);
            $holiday->removePlan($this);
        }
        return $this;
    }
}
$plan = $em->find('Slaplan', 1);

$holiday = new Slaholiday();
// set data on $holiday
// no need to persist $holiday, because you have a cascade={"ALL"} all on the association

$plan->addHoliday($holiday);
// no need to persist $plan, because it's managed by the entitymanager (unless you don't use change tracking policy "DEFERRED_IMPLICIT" (which is used by default))
$em->flush();