Search code examples
phpdoctrine-ormcascadecascading-deletes

Doctrine 2 : ManyToOne cascade remove causes the referenced entity to be deleted


I have a setup where I have product feeds, and each feed has many products. The very simplified setup looks something like this:

Feed model:

/**
 * Class Feed represents a single feed as supplier by a supplier
 * @package App\Model
 * @Entity @Table(name="feeds")
 */
class Feed
{
    /**
     * @var int
     * @Id @Column(type="integer") @GeneratedValue
     */
    protected $id;
}

Product model:

/**
 * Class Product is the base for either supplied and current products
 * @package App\Model
 */
class Product
{
    /**
     * @var int
     * @Id @Column(type="integer") @GeneratedValue
     */
    protected $id;

    /**
     * @var Feed
     * @ManyToOne(targetEntity="App\Model\Feed", cascade={"remove"})
     * @JoinColumn(name="id_feed", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $feed;
}

Now as you can see I have cascading enabled, because I want all of the products to be deleted automatically when a feed is deleted.

However... At the moment, when I delete a product, it causes the original feed te be deleted as well. I suspect it has something to do with how the relation is setup, but I can't seem to figure out where it's wrong.

Can anyone show more light on this situation?


Solution

  • Feed Model :

        /**
         * Class Feed represents a single feed as supplier by a supplier
         * @package App\Model
         * @Entity @Table(name="feeds")
         */
        class Feed
        {
            /**
             * @var int
             * @Id @Column(type="integer") @GeneratedValue
             */
             protected $id;
    
           /**
            * @var Feed
            * @OneToMany(targetEntity="App\Model\Product", mappedBy="feed", orphanRemoval=true, cascade={"remove"})
            * 
            */
            protected $products;    
    
        }
    

    Product Model :

    /**
     * Class Product is the base for either supplied and current products
     * @package App\Model
     */
    class Product
    {
        /**
         * @var int
         * @Id @Column(type="integer") @GeneratedValue
         */
        protected $id;
    
        /**
         * @var Feed
         * @ManyToOne(targetEntity="App\Model\Feed", inversedBy="products")
         * @JoinColumn(name="id_feed", referencedColumnName="id")
         */
        protected $feed;
    }
    

    Now, if you delete a Feed object, Product objects linked to this Feed will be deleted too.

    This is bidirectional relation.

    More info :

    cascade={"remove"}

    • Entity on the inverse side will be deleted while the owning side (Feed) is deleted but only if the entity (Product) is not owned by another than Feed.

    orphanRemoval="true"

    • Same as above but ORM ignores if entity (Product) is owned by another Entity