【问题标题】:Doctrine 2 not persisting the relation from owning side one to Many原则 2 不坚持从拥有一方到多方的关系
【发布时间】:2012-08-17 08:01:02
【问题描述】:

我有这个代码

// ONE to many Bidir -- inverse side
    /**
     * @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
     **/
    protected $items;

另一边

// ONE to many Bidir-- own side
    /**
     * @ORM\ManyToOne(targetEntity="Room", inversedBy="items")
     * @ORM\JoinColumn(name="room_id", referencedColumnName="id")
     **/
    protected $room;

我的问题是我进入项目页面并选择了 Room ,然后我可以在 Room 页面中看到预先选择的项目

但如果我进入房间页面并尝试多选许多项目,那么这些项目不会被保留

编辑:我已经看到它只发生在 OneToMany 关系中。对于多对多来说,他们工作得很好

EDIT2:

我说的是我有表单和选择框的后端区域,我可以在其中选择多个项目。此表单/CRUD 代码/控制器由学说生成。所以我不需要添加任何额外的功能。无论如何,这是我的控制器代码

$editForm   = $this->createForm(new RoomType(), $entity);


        $request = $this->getRequest();

        $editForm->bindRequest($request);
        if ($editForm->isValid()) {
            $em->persist($entity);
            $em->flush();

当我尝试像这样在控制器中穿行时

foreach($entity->getItems() as $item)
        echo $item;

然后我可以在那里看到所有你的项目。所以这意味着所有项目都在主要对象中,但它没有持久化它们。我不知道为什么。

如果有欠款,反面问题。我怎样才能将关系从由于反向和反向转换为拥有

【问题讨论】:

  • 不确定你的代码是什么样的,或者你的数据库,一些例子会很有用。

标签: php symfony doctrine-orm


【解决方案1】:

根据注释中的 cmets,您的代码是错误的。

这是拥有方,因为您指定了inversedBy 属性:

/**
 * ONE to many Bidir-- Inverse side
 * @ORM\ManyToOne(targetEntity="Room", inversedBy="items")
 * @ORM\JoinColumn(name="room_id", referencedColumnName="id")
 **/
protected $room;

这是反面(因为它有mappedBy属性):

/**
 * ONE to many Bidir -- owning side
 * @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
 **/
protected $items;

所以你的代码说:Item 是拥有方,Room 是反方。

双向关系的拥有方必须引用其 OneToOne 的 inversedBy 属性 的反边使用, ManyToOne 或 ManyToMany 映射声明。 inversedBy 属性 指定实体中作为反面的字段 关系。

为了让它更干净:

拥有方必须使用 OneToOne 的 inversedBy 属性, ManyToOne 或 ManyToMany 映射声明。 inversedBy 属性 包含反面关联字段的名称。

而反面:

双向关系的反面必须引用它的 拥有 OneToOne 的 ma​​ppedBy 属性use, OneToMany 或 ManyToMany 映射声明。 mappedBy 属性 指定实体中作为所有者的字段 关系。

再说一遍:

反面要使用OneToOne的mappedBy属性, OneToMany 或 ManyToMany 映射声明。 mappedBy 属性 包含拥有方的关联字段的名称。

另外,另一个重要的考虑因素:

ManyToOne 始终是双向关联的拥有方。

OneToMany 始终是双向关联的反面

因此,对于从反面(房间)持久化的项目,您必须检查已选择/取消选择的项目以及房间是否已包含该项目。

【讨论】:

  • 我可能错了,说哪一方拥有和反向,但代码应该双向工作。我在每一边和两边都使用了级联{persist},但它没有用。即使你没有那个房间的项目,我选择了 5 个项目,数据库中也没有任何内容。这正在发生在另一门课上。所以我想我需要在我的代码中添加一些东西才能发生逆向。无论拥有什么和反面,我的代码都好吗
【解决方案2】:

只需使用循环来设置空间。项目是欠面,您正在编辑反面(房间)。 Symfony2 在编辑逆序时从不更新欠边。

对您来说最简单的解决方案是在持久化房间之前使用循环:

foreach($entity->getItems() as $item){
    $item->setRoom($room);
}

反面级联:

/**
 * @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
 **/
protected $items;

对于我的项目,我基于收集事件侦听器制作了可重用的解决方案。 如果你有时间和技能,我鼓励你也这样做

【讨论】:

  • 我认为我还需要在循环中保留项目。你说的是哪个收藏活动,能给我参考或者链接吗?
  • 如果你在反面有级联,你不必坚持它们。如果您在保存所有对象数据之前获得它,但没有父 - 房间。
  • 了解表单事件:stackoverflow.com/questions/9651095/…,集合只是表单嵌入项
猜你喜欢
  • 2022-01-26
  • 2012-06-06
  • 1970-01-01
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
相关资源
最近更新 更多