Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

But if i go to Room page and i try to multiselect many items , then those are not persisted

EDIT: I have seen that it is only happening for OneToMany relation ship. For Manyto Many they are working fine

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. 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

like image 466
Mirage Avatar asked Aug 17 '12 08:08

Mirage


People also ask

What is owning side in jpa?

The owning side is responsible for propagating the update of the relationship to the database. Usually this is the side with the foreign key. The inverse side maps to the owning side.

What is owning side and inverse side?

And it's easy to remember: the owning side is where the foreign key column lives in the database. In this case, the answer table will have a question_id column so this is the "owning" side. The OneToMany side is called the inverse side.

Which one of the below options is used to define the non owning side of the relationship?

The @JoinColumn annotation helps us specify the column we'll use for joining an entity association or element collection. On the other hand, the mappedBy attribute is used to define the referencing side (non-owning side) of the relationship.


1 Answers

Your code is wrong, based on your comments in annotations.

This is the owning side, because you specify the inversedBy attribute:

/**
 * 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):

/**
 * 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.

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. The inversedBy attribute designates the field in the entity that is the inverse side of the relationship.

To make it more clean:

The owning side has to use the inversedBy attribute of the OneToOne, ManyToOne, or ManyToMany mapping declaration. The inversedBy attribute contains the name of the association-field on the inverse-side.

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. The mappedBy attribute designates the field in the entity that is the owner of the relationship.

And, again:

The inverse side has to use the mappedBy attribute of the OneToOne, OneToMany, or ManyToMany mapping declaration. The mappedBy attribute contains the name of the association-field on the owning side.

Plus, another important consideration:

ManyToOne is always the owning side of a bidirectional assocation.

OneToMany is always the inverse side of a bidirectional assocation

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.

like image 58
gremo Avatar answered Oct 02 '22 06:10

gremo