I have a quite complex entity here and I do not know what is wrong. Let's assume it is a product which has self references for parent product, cross sells, up sells and additional sales. I have an entity with all those filled but a parent product. Now I want to delete it and get the mysql error
An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`product`, CONSTRAINT `FK_D34A04AD2C7E20A` FOREIGN KEY (`parent_product_id`) REFERENCES `product` (`id`))
This is kind of strange, because I do not have a parent_product set on this one and I have no reference to this product as a parent (I manually checked it) ..
If I do the delete action directly on the db, I get the same error with another reference to crossSells (which is understandable, as there really are such references).
In my code I now want to delete those references by hand because somehow the cascade remove statement is not enough / not working.
So I get a product and do remove everything by hand, but I still get the same error as above and still do not even have a parent product id on the one I get the error from. The deletion of the references is not working either.
If you look at the controller you will see some things I added to be sure the correct objects are edited / removed .. Nothing works here
My code
Product Entity
#[ORM\ManyToOne(targetEntity: "Product", inversedBy: 'childProducts')]
private Product|null $parentProduct;
#[ORM\OneToMany(mappedBy: "parentProduct", targetEntity: "Product")]
private $childProducts;
#[ORM\ManyToMany(targetEntity: 'Product', inversedBy: 'additionalSoldToProducts', cascade: ['persist', 'remove'])]
#[ORM\JoinTable(name: 'additional_sales_products')]
#[ORM\JoinColumn(name: 'product_id', referencedColumnName: 'id')]
#[ORM\InverseJoinColumn(name: 'additional_sales_product_id', referencedColumnName: 'id')]
private $additionalSales;
#[ORM\ManyToMany(targetEntity: 'Product', mappedBy: 'additionalSales')]
private $additionalSoldToProducts;
#[ORM\ManyToMany(targetEntity: 'Product', inversedBy: 'crossSellToProducts', cascade: ['persist', 'remove'])]
#[ORM\JoinTable(name: 'cross_sell_products')]
#[ORM\JoinColumn(name: 'product_id', referencedColumnName: 'id')]
#[ORM\InverseJoinColumn(name: 'cross_sell_id', referencedColumnName: 'id')]
private $crossSells;
#[ORM\ManyToMany(targetEntity: 'Product', mappedBy: 'crossSells')]
private $crossSellToProducts;
#[ORM\ManyToMany(targetEntity: 'Product', inversedBy: 'upsellToProducts', cascade: ['persist', 'remove'])]
#[ORM\JoinTable(name: 'upsell_products')]
#[ORM\JoinColumn(name: 'product_id', referencedColumnName: 'id')]
#[ORM\InverseJoinColumn(name: 'up_id', referencedColumnName: 'id')]
private $upsells;
#[ORM\ManyToMany(targetEntity: 'Product', mappedBy: 'upsells')]
private $upsellToProducts;
Controller
/**
* @return void
*/
private function deleteMarkedProducts(): void
{
/**
* @var $product Product
*/
$products = $this->productRepo->findBy(['toDelete' => true]);
foreach ($products as $product) {
$product = $this->removeAttributesOfProduct($product);
$product = $this->removeParentProductFromChildProducts($product);
$product = $this->removeCrossSellProducts($product);
$product = $this->removeAdditionalSoldToProducts($product);
$product = $this->managerRegistry->getRepository(Product::class)->find($product->getId());
$entityManager = $this->managerRegistry->getManager();
$entityManager->remove($product);
$entityManager->flush();
}
}
Thanks a lot!
CodePudding user response:
Use property orphanRemoval=true
at field $childProducts
For more information see Diffrence between orphanRemoval=True and cascade="remove"