Home > Net >  Symfony / Doctrine Entity not deletable - mysql error code 1451
Symfony / Doctrine Entity not deletable - mysql error code 1451

Time:08-08

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"

  • Related