doudui5753 2014-07-22 19:08
浏览 54
已采纳

Doctrine 2 ArrayCollections - 我错过了什么吗?

I have a bidirectional many-to-one relationship. Let's go with Foo and Bar. Foo has the following:

class Foo
{
    /**
     * @ORM\OneToMany(targetEntity="Bar", mappedBy="foo", cascade={"all"}, orphanRemoval=true)
     */
    private $bars;

    public function __construct()
    {
        $this->bars = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @param mixed $bars
     */
    public function setBars($bars)
    {
        $this->bars = $bars;
    }

    /**
     * @param Bar $bar
     */
    public function addBar(Bar $bar)
    {
        $this->bars->add($bar);
    }

    /**
     * @return mixed
     */
    public function getBars()
    {
        return $this->bars;
    }
}

And Bar:

class Bar
{
    /**
     * @ORM\Id()
     * @ORM\ManyToOne(targetEntity="Foo", inversedBy="bars")
     * @ORM\JoinColumn(name="foo_id", referencedColumnName="id", nullable=false)
     */
    protected $foo;

    /**
     * @param Foo $foo
     */
    public function setFoo(Foo $foo)
    {
        $this->foo = $foo;
    }

    /**
     * @return Foo
     */
    public function getFoo()
    {
        return $this->foo;
    }
}

Okay, so with the classes above, when I write:

$foo = new Foo();

$bar1 = new Bar();
$bar2 = new Bar();

$foo->addBar($bar1);
$foo->addBar($bar2);

And try to persist, I get an error about how each Bar's foo property is null:

enter image description here

Similarly, if I flip it around to:

$foo = new Foo();

$bar1 = new Bar();
$bar2 = new Bar();

$bar1->setFoo($foo);
$bar2->setFoo($foo);

I can persist, but then my Foos newly generated PersistentCollection for that property is empty:

enter image description here

Is this intended behavior? I'm used to other ORMs on different platforms wiring up the bidirectional relationship upon assignment, so I'm not sure if this is normal for Doctrine/PHP, or if my annotations are messed up (which the error message above leads me to believe).

So, any help would be greatly appreciated.

  • 写回答

4条回答 默认 最新

  • doupingzhi9674 2014-07-22 19:22
    关注

    You need to set the two sides of the association, for instance

    /**
     * @param Bar $bar
     */
    public function addBar(Bar $bar)
    {
        if(!$this->bars->contains($bar)) {
            $this->bars->add($bar);
            $bar->setFoo($this);
        }
    }
    ----
    /**
     * @param Foo $foo
     */
    public function setFoo(Foo $foo)
    {
        if($this->foo !== $foo) {
            $this->foo = $foo;
            $foo->addBar($this);
        }
    }
    

    At the moment your only setting one side of the association and Doctrine does not do the rest for you.

    If you don't want to modify your add/remove methods you have to

     $bar->setFoo($foo)
     $foo->addBar($bar)
    

    Everytime you want to add a foo or a bar

    EDIT:

    If you want to use only one side to do all the operation, read about owning/inverse side. Maybe it could help with your problem. But I'm not sure it will do the correct bidir link between your entities.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画