1

In a Doctrine entity I've got this configuration:

/**
 * @var \Doctrine\Common\Collections\ArrayCollection
 * @ORM\ManyToMany(targetEntity="PriceRate", cascade={"all"}, orphanRemoval=true)
 * @ORM\JoinTable(name="product_rates",
 *   joinColumns={@ORM\JoinColumn(name="product_id",referencedColumnName="id")},
 *   inverseJoinColumns={@ORM\JoinColumn(name="rate_id",referencedColumnName="id")})
 */
protected $rates;

When I delete the entity it tries to delete the price_rate table first, instead of the joined table so I get the following error:

Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (uniski.product_rates, CONSTRAINT FK_15A90A8FBC999F9F FOREIGN KEY (rate_id) REFERENCES price_rate (id))

Why is it not trying to delete the joined table rows first? I've tried to add onDelete statements on the join table columns but it didn't work.

This is a unidirectional relationship because PriceRate is used by other entities, therefore i'm using a ManyToMany relationship.

The only way it works is before removing the entity is to clear the ArrayCollection of the child entities like so:

$product->removeAllRate(); //it does this: $this->rates->clear();

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

Thanks!

Jason Roman
  • 8,146
  • 10
  • 35
  • 40
  • this post helped to me: https://stackoverflow.com/questions/14257004/doctrine2-symfony2-cascading-remove-integrity-constraint-violation-1451. Regards – Albeis Aug 08 '17 at 13:19

2 Answers2

0

In the entity, you have to specify ManyToMany relation as well. This is the reason. Example:

/**
 * @ORM\ManyToMany(targetEntity="Product", mappedBy="rates")
 */
private $products;
Vladislav
  • 357
  • 1
  • 8
  • May be this is why there is no shorter way to do it, I have to remove first all children entities. I can't add the other side relationship because the rates is shared among other types of entities. If rates are only used by products I could use your solution. A part from the archeticture issue, if I don't change it, removing the child entities first is the olny way, which is not so bad at the moment. – Victor Salvans Montesó Aug 09 '17 at 10:36
0

I had this same issue, with this specific:

This is a unidirectional relationship because PriceRate is used by other entities, therefore i'm using a ManyToMany relationship.

I could make it works with adding onDelete="cascade" on both joinColumns So mine looks like that:

 * @ORM\ManyToMany(targetEntity="PriceRate", cascade={"persist", "remove"})
 * @ORM\JoinTable(name="product_rates",
 *      joinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id", onDelete="cascade")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="rate_id", referencedColumnName="id", unique=true, onDelete="cascade")}
 * )

Note that I have a few differences: my cascade= is more restrictive here, I have a unique=true on the inverseJoinColumns, and I didn't need the orphanRemoval

user1657853
  • 141
  • 5