N
N
nepster-web2016-11-17 18:43:46
symfony
nepster-web, 2016-11-17 18:43:46

For what reason, when saving an entity with a one to many relationship, is the id not written to the relationship?

There are 2 entities:

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="products")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProductRepository")
 */
class Product
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=100)
     */
    private $name;

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="products", cascade={"ALL"})
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id", onDelete="CASCADE")
     */
    private $category;

    /**
     * @ORM\OneToMany(targetEntity="Image", mappedBy="product")
     */
    private $images;

    /**
     * Product constructor.
     */
    public function __construct()
    {
        $this->images = new ArrayCollection();
    }
    ...
}

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Table(name="images")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ImageRepository")
 */
class Image
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Product", inversedBy="images", cascade={"ALL"})
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
     */
    private $product;

    ...
}

Everything is simple here, the product can have images.
Now there is the following code for saving this case to the repository:
$product = new Product();
        $product->setName('Новый товар 1');

        $category = new Category();
        $category->setName('preview_1');

        $product->setCategory($category);

        $image1 = new Image();
        $image2 = new Image();
        $image3 = new Image();

        $product->addImage($image1);
        $product->addImage($image2);
        $product->addImage($image3);

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

        $em->persist($category);

        $em->persist($image1);
        $em->persist($image2);
        $em->persist($image3);

        $em->persist($product);

        $em->flush();

And the problem is that when saving images, they are not given a product_id. For a long time I could not understand what the problem was, copy paste from the docks did not solve the problem. Although the many-to-one relationship worked as expected.
I spent all day looking for the problem and accidentally came across the following entry:
...
public function addImage(\AppBundle\Entity\Image $image)
    {
        $this->images[] = $image;

        $image->setProduct($this);

        return $this;
    }
...

That is, in the Product entity in the addImage method, you must add the line $image->setProduct($this); , it seems logical, everything works. But I did not find any mention of this in the docs, and moreover, it was not included when generating my entity schema using the command:
php bin/console doctrine:generate:entities AppBundle/Entity/Product

Please tell me why the command does not generate a fully working version, maybe I missed something?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis, 2016-11-17
@nepster-web

symfony.com/doc/current/reference/forms/types/coll...
Need to explicitly persist the reverse side. The manager of nothing knows about your images when a product arrives.
Also, all the details when working with associations are described here
docs.doctrine-project.org/projects/doctrine-orm/en...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question