带有oneToMany字段的Doctrine更新模型

时间:2014-06-17 17:19:00

标签: database symfony orm doctrine-orm doctrine

无法从万维网上获得太多帮助......

情况是:

  • 我的模型有两个manyToMany字段和一个oneToMany字段。
  • 当我更新模型时,doctrine会神奇地删除manyToMany字段的旧值并设置新值,
  • 但是对于oneToMany字段,它不会删除旧值,而是添加新值。

这是正常行为吗?

要解决此问题,我正在使用DQL来清空映射的模型ID并保留新值的oneToMany字段目标实体

即模型:规则有

/**
* @OneToMany(targetEntity="\Tier", mappedBy="rule", cascade={"persist", "remove"})
* @JoinColumn(name="ruleId", referencedColumnName="ruleId")
* @var Tier[]
*/
public $tiers;

在规则映射器中,我在调用PERSIST之前删除所有层,以使UPDATE工作:

public function resetTiers($ruleId)
{
$modelClass = "Tier";

$q = $this->doctrineEntityManager->createQuery("Delete from $modelClass m where m.rule =" . $ruleId);
$numDeleted = $q->execute();

return $numDeleted;
}

我不介意这样做,只要它没有,并且没有引入任何不良做法。

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

请阅读this bit of Doctrine's documentation

  

Doctrine只会检查协会的拥有方是否有变更。

  

OneToMany始终是双向关联的反面。

虽然:

  

您可以自己选择多对多关联的拥有方。

是的,这是正常行为。

我的猜测是你的ManyToMany关系归你的模型所有(即你在你的财产评论中说明inversedBy而不是mappedBy的主义声明。这就是他们自动更新的原因(根据上面链接的文档)。

所以要么你开始在另一方的实体(即Tier)上工作,要么通过你的Rule的访问者直接更新另一方的实体来欺骗ORM,可能是这样的: / p>

public function setTiers($tiers) {
    foreach ($this->tiers as $tier) {
        $tier->setRule(null);
    }
    foreach ($tiers as $tier) {
        $tier->setRule($this);
    }
    if (is_array($tiers)) {
        //this wrapper is useful if you use syntaxes like
        //$someRule->getTiers()->add($someTier); which is usual if you use
        //an addTier(Tier $tier) method declared in Rule
        $tiers = new \Doctrine\Common\Collections\ArrayCollection($tiers);
    }
    $this->tiers = $tiers;
}

对于第一个选项,处理其他方的实体,只需拨打$someTier->setRule($someRule)即可自动更新* $someRule的{​​{1}}。

*:自动更新应该发生1 /当你刷新你的mod和2 /你可能需要刷新$tiers对象(我的意思是EM的$someRule方法)。

所有这些都是“我的猜测”,任何人都可以随意纠正,如果您尝试这个,OP可以随意提供一些反馈意见! ;)

以下是关于更新相关实体的some more doc,特别是在页面底部的第6.14.1节。

希望这有帮助!