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:
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
/**
* 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 {
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=45, nullable=false)
* @Assert\NotBlank(message="Por favor, escriba el nombre del producto.")
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* @var string
*
* @ORM\Column(name="code", type="string", length=45, nullable=false)
*/
private $code;
/**
* @var string
*
* @ORM\Column(name="description_long", type="text", nullable=false)
*/
private $descriptionLong;
/**
* @var integer
*
* @ORM\Column(name="amount_per_unit", type="integer", nullable=false)
*/
private $amountPerUnit;
/**
* @var string
*
* @ORM\Column(name="weight", type="decimal", precision=11, scale=3, nullable=false)
*/
private $weight;
/**
* @var string
*
* @ORM\Column(name="web", type="string", length=100, nullable=false)
*/
private $web;
/**
* @var boolean
*
* @ORM\Column(name="isActive", type="boolean", nullable=false)
*/
private $isactive;
/**
* @var \DateTime
*
* @ORM\Column(name="createdtime", type="datetime", nullable=false)
* @Assert\DateTime()
*/
private $createdtime;
/**
* @var \DateTime
*
* @ORM\Column(name="modifiedtime", type="datetime", nullable=false)
* @Assert\DateTime()
*/
private $modifiedtime;
/**
* @var \DateTime
*
* @ORM\Column(name="deletedtime", type="datetime", nullable=true)
*/
private $deletedtime;
/**
* @var boolean
*
* @ORM\Column(name="isDeleted", type="boolean", nullable=false)
*/
private $isdeleted;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var \AppBundle\Entity\Categories
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Categories")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
* })
*/
private $category;
/**
* @var \AppBundle\Entity\ProductTypes
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\ProductTypes")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="type", referencedColumnName="id")
* })
*/
private $type;
/**
* @var \AppBundle\Entity\Currencies
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Currencies")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="currency_id", referencedColumnName="id")
* })
*/
private $currency;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Sets", inversedBy="product")
* @ORM\JoinTable(name="products_sets",
* joinColumns={
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="set_id", referencedColumnName="id")
* }
* )
*/
private $set;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Products", mappedBy="productParentid")
*/
private $product;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Documents", inversedBy="product")
* @ORM\JoinTable(name="product_attachments",
* joinColumns={
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="document_id", referencedColumnName="id")
* }
* )
*/
private $document;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Images", inversedBy="product")
* @ORM\JoinTable(name="products_images",
* joinColumns={
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="image_id", referencedColumnName="id")
* }
* )
*/
private $image;
// CUSTOM CODE
/**
* @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;
}
/**
* Set name
*
* @param string $name
* @return Products
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
/**
* Set description
*
* @param string $description
* @return Products
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription() {
return $this->description;
}
/**
* Set code
*
* @param string $code
* @return Products
*/
public function setCode($code) {
$this->code = $code;
return $this;
}
/**
* Get code
*
* @return string
*/
public function getCode() {
return $this->code;
}
/**
* Set descriptionLong
*
* @param string $descriptionLong
* @return Products
*/
public function setDescriptionLong($descriptionLong) {
$this->descriptionLong = $descriptionLong;
return $this;
}
/**
* Get descriptionLong
*
* @return string
*/
public function getDescriptionLong() {
return $this->descriptionLong;
}
/**
* Set amountPerUnit
*
* @param integer $amountPerUnit
* @return Products
*/
public function setAmountPerUnit($amountPerUnit) {
$this->amountPerUnit = $amountPerUnit;
return $this;
}
/**
* Get amountPerUnit
*
* @return integer
*/
public function getAmountPerUnit() {
return $this->amountPerUnit;
}
/**
* Set weight
*
* @param string $weight
* @return Products
*/
public function setWeight($weight) {
$this->weight = $weight;
return $this;
}
/**
* Get weight
*
* @return string
*/
public function getWeight() {
return $this->weight;
}
/**
* Set web
*
* @param string $web
* @return Products
*/
public function setWeb($web) {
$this->web = $web;
return $this;
}
/**
* Get web
*
* @return string
*/
public function getWeb() {
return $this->web;
}
/**
* Set isactive
*
* @param boolean $isactive
* @return Products
*/
public function setIsactive($isactive) {
$this->isactive = $isactive;
return $this;
}
/**
* Get isactive
*
* @return boolean
*/
public function getIsactive() {
return $this->isactive;
}
/**
* Set createdtime
*
* @param \DateTime $createdtime
* @return Products
*/
public function setCreatedtime($createdtime) {
$this->createdtime = $createdtime;
return $this;
}
/**
* Get createdtime
*
* @return \DateTime
*/
public function getCreatedtime() {
return $this->createdtime;
}
/**
* Set modifiedtime
*
* @param \DateTime $modifiedtime
* @return Products
*/
public function setModifiedtime($modifiedtime) {
$this->modifiedtime = $modifiedtime;
return $this;
}
/**
* Get modifiedtime
*
* @return \DateTime
*/
public function getModifiedtime() {
return $this->modifiedtime;
}
/**
* Set deletedtime
*
* @param \DateTime $deletedtime
* @return Products
*/
public function setDeletedtime($deletedtime) {
$this->deletedtime = $deletedtime;
return $this;
}
/**
* Get deletedtime
*
* @return \DateTime
*/
public function getDeletedtime() {
return $this->deletedtime;
}
/**
* Set isdeleted
*
* @param boolean $isdeleted
* @return Products
*/
public function setIsdeleted($isdeleted) {
$this->isdeleted = $isdeleted;
return $this;
}
/**
* Get isdeleted
*
* @return boolean
*/
public function getIsdeleted() {
return $this->isdeleted;
}
/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/**
* Set category
*
* @param \AppBundle\Entity\Categories $category
* @return Products
*/
public function setCategory(\AppBundle\Entity\Categories $category = null) {
$this->category = $category;
return $this;
}
/**
* Get category
*
* @return \AppBundle\Entity\Categories
*/
public function getCategory() {
return $this->category;
}
/**
* Set type
*
* @param \AppBundle\Entity\ProductTypes $type
* @return Products
*/
public function setType(\AppBundle\Entity\ProductTypes $type = null) {
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return \AppBundle\Entity\ProductTypes
*/
public function getType() {
return $this->type;
}
/**
* Set currency
*
* @param \AppBundle\Entity\Currencies $currency
* @return Products
*/
public function setCurrency(\AppBundle\Entity\Currencies $currency = null) {
$this->currency = $currency;
return $this;
}
/**
* Get currency
*
* @return \AppBundle\Entity\Currencies
*/
public function getCurrency() {
return $this->currency;
}
/**
* Add set
*
* @param \AppBundle\Entity\Sets $set
* @return Products
*/
public function addSet(\AppBundle\Entity\Sets $set) {
$this->set[] = $set;
return $this;
}
/**
* Remove set
*
* @param \AppBundle\Entity\Sets $set
*/
public function removeSet(\AppBundle\Entity\Sets $set) {
$this->set->removeElement($set);
}
/**
* Get set
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getSet() {
return $this->set;
}
/**
* Add product
*
* @param \AppBundle\Entity\Products $product
* @return Products
*/
public function addProduct(\AppBundle\Entity\Products $product) {
$this->product[] = $product;
return $this;
}
/**
* Remove product
*
* @param \AppBundle\Entity\Products $product
*/
public function removeProduct(\AppBundle\Entity\Products $product) {
$this->product->removeElement($product);
}
/**
* Get product
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProduct() {
return $this->product;
}
/**
* Add document
*
* @param \AppBundle\Entity\Documents $document
* @return Products
*/
public function addDocument(\AppBundle\Entity\Documents $document) {
$this->document[] = $document;
return $this;
}
/**
* Remove document
*
* @param \AppBundle\Entity\Documents $document
*/
public function removeDocument(\AppBundle\Entity\Documents $document) {
$this->document->removeElement($document);
}
/**
* Get document
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getDocument() {
return $this->document;
}
/**
* Add image
*
* @param \AppBundle\Entity\Images $image
* @return Products
*/
public function addImage(\AppBundle\Entity\Images $image) {
$this->image[] = $image;
return $this;
}
/**
* Remove image
*
* @param \AppBundle\Entity\Images $image
*/
public function removeImage(\AppBundle\Entity\Images $image) {
$this->image->removeElement($image);
}
/**
* Get image
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getImage() {
return $this->image;
}
// CUSTOM CODE
/**
* Set providerRate
*
* @param \AppBundle\Entity\ProviderRate $providerRate
* @return Products
*/
/* public function setProviderRate(\AppBundle\Entity\ProviderRate $providerRate = null)
{
$this->providerRate = $providerRate;
return $this;
}
*/
/**
* 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
/**
* 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 string
*
* @ORM\Column(name="reference", type="string", length=45, nullable=false)
*/
private $reference;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="description", type="string", length=255, nullable=false)
*/
private $description;
/**
* @var integer
*
* @ORM\Column(name="amount_per_unit", type="integer", nullable=true)
*/
private $amountPerUnit;
/**
* @var string
*
* @ORM\Column(name="unit_price", type="decimal", precision=25, scale=3, nullable=false)
*/
private $unitPrice;
/**
* @var string
*
* @ORM\Column(name="discount", type="decimal", precision=25, scale=3, nullable=false)
*/
private $discount;
/**
* @var \AppBundle\Entity\Providers
*
* @ORM\Id
* @ORM\GeneratedValue(strategy="NONE")
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Providers")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="provider_id", referencedColumnName="id")
* })
*/
private $provider;
/**
* @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 provider
*
* @param \AppBundle\Entity\Providers $provider
* @return ProviderRate
*/
public function setProvider(\AppBundle\Entity\Providers $provider)
{
$this->provider = $provider;
return $this;
}
/**
* Get provider
*
* @return \AppBundle\Entity\Providers
*/
public function getProvider()
{
return $this->provider;
}
/**
* 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:
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));
}
SOLVE:
I can solve it. The code of my entities thats ok. I change the controller function. First I create the product object, set the providerRate to null and them persist it. After I create the providerRate object and set the product object.