简体   繁体   English

教义2没有坚持从拥有一方到多方的关系

[英]Doctrine 2 not persisting the relation from owning side one to Many

I have this code 我有这个代码

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

The other side 另一边

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

My Problem is that i go to item page and i select Room , then i can see items preselecetd in Room page 我的问题是,我去项目页面,我选择房间,然后我可以在房间页面看到项目preselecetd

But if i go to Room page and i try to multiselect many items , then those are not persisted 但是,如果我进入Room页面并尝试多选多个项目,那么这些项目就不会持久化

EDIT: I have seen that it is only happening for OneToMany relation ship. 编辑:我已经看到它只发生在OneToMany关系船上。 For Manyto Many they are working fine 对于Manyto很多人来说,他们工作正常

EDIT2: EDIT2:

I am talking about the backend area where i have the form and select box where i can select multiple items. 我说的是后端区域,我有表格和选择框,我可以选择多个项目。 This form/CRUD code / controllers are genrated by doctrine. 这种形式/ CRUD代码/控制器由学说生成。 SO i don't need to add any extra function. 所以我不需要添加任何额外的功能。 Any way this is my controller code 这是我的控制器代码

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


        $request = $this->getRequest();

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

When i try to walk through in controller like this 当我试图在这样的控制器中走过

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

Then i can see all thye items there. 然后我可以看到那里的所有项目。 So it means all items are there in main object but its not persisting them. 因此,它意味着所有项目都存在于主要对象中,但它不会持久存在。 i don't know why. 我不知道为什么。

If there is owing , reverse side problem. 如果有欠,反面问题。 How can i chnage the relationship from owing to inverse and inverse to owning 我怎样才能将这种关系从反向和反向转变为拥有

Your code is wrong, based on your comments in annotations. 根据您在注释中的注释,您的代码是错误的。

This is the owning side , because you specify the inversedBy attribute: 这是拥有方 ,因为您指定了inversedBy属性:

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

This is the inverse side (because it has the mappedBy attribute): 这是反面 (因为它具有mappedBy属性):

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

So your code says: Item is the owning side, Room is the inverse side. 所以你的代码说: Item是拥有的一方, Room是反面的。

The owning side of a bidirectional relationship must refer to its inverse side by use of the inversedBy attribute of the OneToOne, ManyToOne, or ManyToMany mapping declaration. 双向关系的拥有方必须通过使用 OneToOne,ManyToOne或ManyToMany映射声明的inversedBy 属性来引用其反面。 The inversedBy attribute designates the field in the entity that is the inverse side of the relationship. inversedBy属性指定实体中的字段,该字段是关系的反面。

To make it more clean: 为了使它更干净:

The owning side has to use the inversedBy attribute of the OneToOne, ManyToOne, or ManyToMany mapping declaration. 拥有方必须使用OneToOne,ManyToOne或ManyToMany映射声明的inversedBy属性。 The inversedBy attribute contains the name of the association-field on the inverse-side. inversedBy属性包含反面的关联字段的名称。

While, for the inverse side: 而对于反方:

The inverse side of a bidirectional relationship must refer to its owning side by use of the mappedBy attribute of the OneToOne, OneToMany, or ManyToMany mapping declaration. 双向关系的反面必须通过使用 OneToOne,OneToMany或ManyToMany映射声明的mappedBy属性来引用其拥有方。 The mappedBy attribute designates the field in the entity that is the owner of the relationship. mappedBy属性指定作为关系所有者的实体中的字段。

And, again: 然后再次:

The inverse side has to use the mappedBy attribute of the OneToOne, OneToMany, or ManyToMany mapping declaration. 反面必须使用OneToOne,OneToMany或ManyToMany映射声明的mappedBy属性。 The mappedBy attribute contains the name of the association-field on the owning side. mappedBy属性包含拥有方的关联字段的名称。

Plus, another important consideration: 另外,另一个重要的考虑:

ManyToOne is always the owning side of a bidirectional assocation. ManyToOne始终是双向关联的拥有方。

OneToMany is always the inverse side of a bidirectional assocation OneToMany始终是双向关联的反面

Thus, for persisting items from the inverse side (room), you have to check which item has been selected/deselected and if room already contains that item or not. 因此,对于从反面(房间)保留项目,您必须检查已选择/取消选择的项目以及房间是否已包含该项目。

Just use you loop to set room. 只需使用你循环来设置空间。 Item is owing side and you editing inverse side (room). 项目是侧面,你编辑反面(房间)。 Symfony2 never updates owing sides while editing inverse one. Symfony2在编辑逆序时不会更新欠边。

The simplest solution for you is use loop before persisting room: 最简单的解决方案是在持久化之前使用循环:

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

and cascade on inverse side: 和反向级联:

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

For my projects I made reusable solution based on collection events listeners. 对于我的项目,我基于集合事件监听器制作了可重用的解决方案。 If you have time & skills I encourage you to do the same 如果你有时间和技能,我鼓励你也这样做

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM