This forum is in READ-ONLY mode.
You can look around, but if you want to ask a new question, please use Stack Overflow.

Doctrine persist entity with inverse relation not work

New topics about Symfony 2 should go here

Doctrine persist entity with inverse relation not work

by frasodel » Tue Jun 16, 2015 5:10 pm

I'm trying to save two entities linked. Product entity may have any or many entities ProviderRate. When I try to save the product entity, it tells me that ProviderRate related entity has not assigned one of their required fields. I need to save a product with no need to assign a ProviderRate.

The error message showing me is:
Code: Select all
Entity of type AppBundle\Entity\ProviderRate is missing an assigned ID for field 'provider'.
The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called.
If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.


My entitdades code is as follows:

Product Entity
Code: Select all
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Products
 *
 * @ORM\Table(name="products", uniqueConstraints={@ORM\UniqueConstraint(name="id_producto_UNIQUE", columns={"id"})}, indexes={@ORM\Index(name="fk_id_productos_id_categorias1_idx", columns={"category_id"}), @ORM\Index(name="fk_id_productos_id_producto_tipo1_idx", columns={"type"}), @ORM\Index(name="fk_id_productos_id_moneda1_idx", columns={"currency_id"})})
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProductsRepository")
 */
class Products {
   /**
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\ProviderRate", mappedBy="product", cascade={"persist"})
    */
   private $providerRate;

    /**
     * Constructor
     */
    public function __construct() {
      $this->createdtime       = new \DateTime();
      $this->modifiedtime    = new \DateTime();
        $this->set             = new \Doctrine\Common\Collections\ArrayCollection();
        $this->product          = new \Doctrine\Common\Collections\ArrayCollection();
        $this->document       = new \Doctrine\Common\Collections\ArrayCollection();
        $this->image          = new \Doctrine\Common\Collections\ArrayCollection();
      $this->providerRate    = new \Doctrine\Common\Collections\ArrayCollection();
      $this->descriptionLong    = '';
      $this->amountPerUnit    = 1;
      $this->web             = '';
      $this->weight          = 0;
      $this->isdeleted       = 0;
    }

    /**
     * Add providerRate
     *
     * @param \AppBundle\Entity\ProviderRate $providerRate
     * @return Products
     */
    public function addProviderRate(\AppBundle\Entity\ProviderRate $providerRate) {
        $this->providerRate[] = $providerRate;

        return $this;
    }
   
   /**
     * Remove providerRate
     *
     * @param \AppBundle\Entity\ProviderRate $providerRate
     */
    public function removeProviderRate(\AppBundle\Entity\ProviderRate $providerRate) {
        $this->providerRate->removeElement($providerRate);
    }
   
    /**
     * Get providerRate
     *
     * @return \AppBundle\Entity\ProviderRate
     */
    public function getProviderRate()
    {
        return $this->providerRate;
    }
}


ProviderRate Entity
Code: Select all
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ProviderRate
 *
 * @ORM\Table(name="provider_rate", indexes={@ORM\Index(name="fk_proveedor_has_producto_compra_producto_compra1_idx", columns={"product_id"}), @ORM\Index(name="fk_id_tarifa_proveedor_id_moneda1_idx", columns={"currency_id"}), @ORM\Index(name="IDX_3A645C45A53A8AA", columns={"provider_id"})})
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProviderRateRepository")
 */
class ProviderRate
{
    /**
    * @var \AppBundle\Entity\Products
    *
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="NONE")
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Products", inversedBy="providerRate")
    * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
    *
    */
    private $product;

    /**
     * Set product
     *
     * @param \AppBundle\Entity\Products $product
     * @return ProviderRate
     */
    public function setProduct(\AppBundle\Entity\Products $product)
    {
        $this->product = $product;

        return $this;
    }

    /**
     * Get product
     *
     * @return \AppBundle\Entity\Products
     */
    public function getProduct()
    {
        return $this->product;
    }
}


The code to run on the controller is as follows:
Code: Select all
public function ajaxNewProductAction() {
        $request = $this->getRequest();

        $product    = new Products();
        $form       = $this->createForm(new ProductsType(), $product);
        $form->handleRequest($request);
        if ($request->getMethod() == 'POST') {
            if ($form->isSubmitted() && $form->isValid()) { // Se procesa el formulario
                $em             = $this->getDoctrine()->getManager();
                $providerId     = $request->get('provider');
                $productVals    = $request->get('Products');
                $currency       = $em->getRepository('AppBundle:Currencies')->findOneByName("Euro");

                $product->setCurrency($currency);
                $product->setType($em->getRepository('AppBundle:ProductTypes')->findOneById(1));
                $product->setIsactive(1);

                $em->persist($product);
                $em->flush();


                $response['success'] = true;
                $response['data'] = 0;
                $response['providerId'] = $providerId;
            }
            else {
                $response['success'] = false;
                $response['cause'] = 'whatever';
            }
            return new JsonResponse($response);
        }

        return $this->render(':products/ajax:newProduct.html.twig', array("form" => $form->createView(), "edit" => false));
    }
frasodel
Junior Member
 
Posts: 1
Joined: Tue Jun 16, 2015 5:03 pm