Symfony2-Doctrine: ManyToMany relation is not saved to database
Asked Answered
M

2

62

I have two PHP model classes named Category and Item. A Category may have many Items and an Item may belong to many Categories. I have created a ManyToMany relation to both classes:

class Category
{
    /**
     * @ORM\ManyToMany(targetEntity="Item", mappedBy="categories", cascade={"persist"})
     */
    private $items;

    /**
     * Add items
     *
     * @param Ako\StoreBundle\Entity\Item $items
     */
    public function addItems(\Ako\StoreBundle\Entity\Item $items)
    {
        $this->items[] = $items;
    }

    /**
     * Get items
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getItems()
    {
        return $this->items;
    }
}

And:

class Item
{
    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="items", cascade={"persist"})
     * @ORM\JoinTable(name="item_category",
     * joinColumns={@ORM\JoinColumn(name="item_id", referencedColumnName="id")},
     * inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")}
     * )
     */
    private $categories;

    /**
     * Add categories
     *
     * @param Ako\StoreBundle\Entity\Category $categories
     */
    public function addCategories(\Ako\StoreBundle\Entity\Category $categories)
    {
        $this->categories[] = $categories;
    }

    /**
     * Get categories
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getCategories()
    {
        return $this->categories;
    }
}

Now in my controller:

$em = $this->getDoctrine()->getEntityManager();

$item = $em->getRepository('AkoStoreBundle:Item')->find($item_id);
$category = $em->getRepository('AkoStoreBundle:Category')->find($category_id);

$category->addItems($item);

$em->flush();
// Render the same page again.

In this page, I show the list of all items in a select field. The user can select one item, and add it to the category.

The list of items which belong to the category are shown below the form.

When the I submit the form, the selected item is added to the list of Category items, and is shown below, but it is not stored in the database, and if refresh the page, it disappears.

Can anyone please help me with this? Thanks in advance.

Musing answered 12/8, 2011 at 18:45 Comment(1)
Above post helps me lot to map Many to Many mapping in Entity. Is there any good (full) documentation link that show all type of database mapping (entity mappings) ?Derogative
I
95

Your Category entity is the inverse side of the relationship.

Try changing addItems to look like this:

public function addItem(\Ako\StoreBundle\Entity\Item $item)
    {
        $item->addCategory($this);
        $this->items[] = $item;
    }

Note that I changed your plural names to singular, since you're dealing with single entities, not collections.

Impracticable answered 12/8, 2011 at 20:3 Comment(5)
doctrine-project.org/docs/orm/2.0/en/reference/…Pneumatic
Took me some hours of investigating, but when this happens in a Form, you must also set 'by_reference' => false on the corresponding form fields. Otherwise, the add* and remove* methods are never called.Edmanda
And don't do like I did: do not add this method on both sides or yout entities will loop until your server restarts...Pakistan
@Edmanda 'by_reference' => false is only useful with CollectionTypeAmphibology
@Trix is right. Whilst you CAN use "by_reference" with EntityType you will likely run into duplicate key SQL errors. (It only works for removing many-to-many links from the mappedBy side.)Intoxication
S
1

I had the same problems...I think you forgot

$category->addItems($item);
$em->persist($category);
$em->flush();
Scagliola answered 16/4, 2012 at 21:50 Comment(1)
There is no persist() needed because both entities are already managedKoopman

© 2022 - 2024 — McMap. All rights reserved.