Search code examples
symfonyone-to-manysql-deletedelete-rowmany-to-one

symfony2 deleteForm not working fine


I have 2 entities. I would like to delete row of Service.

I tried:

$em = $this->getDoctrine()->getEntityManager();

$service = $em->getRepository('AppBundle:Service')->find(1);

$em->remove($service);

$em->flush();

On this way it deleted all of the row, which containing this category id. Sry for my bad English. Let me explain you on the other way:

           BEFORE                     AFTER delete id 1 from service
+----+------+  +----+------+-----+  +----+------+  +----+------+-----+
+ id + ca_  +  + id + se_  + ca_ +  + id + ca_  +  + id + se_  + ca_ +
+    + name +  +    + name + id  +  +    + name +  +    + name + id  +
+----+------+  +----+------+-----+  +----+------+  +----+------+-----+
+ 1  + A    +  + 1  + A1   + 1   +  +    +      +  +    +      +     +
+----+------+  +----+------+-----+  +----+------+  +----+------+-----+
+ 2  + B    +  + 2  + A2   + 1   +  + 2  + B    +  +    +      +     +
+----+------+  +----+------+-----+  +----+------+  +----+------+-----+
+ 3  + C    +  + 3  + B1   + 2   +  + 3  + C    +  + 3  + B1   + 2   +
+----+------+  +----+------+-----+  +----+------+  +----+------+-----+

How can I fixed that?

Service entity:

/**
* Service
*
* @ORM\Table(name="service")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ServiceRepository")
*/
class Service {
 ...

 /**
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="services", cascade={"persist","remove"})
 * @ORM\JoinColumn(onDelete="CASCADE")
 */
 private $caId;

 /**
 * Set caId
 *
 * @param \AppBundle\Entity\Category $caId
 *
 * @return Service
 */
 public function setCaId(\AppBundle\Entity\Category $caId = null)
 {
     $this->caId = $caId;
     return $this;
 }

 /**
 * Get caId
 *
 * @return \AppBundle\Entity\Category
 */
 public function getCaId()
 {
     return $this->caId;
 }
}

Category entity:

/**
* Category
*
* @ORM\Table(name="category")
* @ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository")
*/
class Category {
 ...

 /**
 * @ORM\OneToMany(
 *   targetEntity="Service",
 *   mappedBy="caId"
 * )
 */
 private $services;

 /**
 * Constructor
 */
 public function __construct()
 {
   $this->services = new ArrayCollection();
 }

 /**
 * Get orders
 *
 * @return Collection
 */
 public function getServices()
 {
   return $this->services;
 }
}


Solution

  • I see two issues with how your mapping is configured:

    1. In your Service entity, you have configured to cascade removal operations. This means that when a Service object is deleted, the Category entity it was associated with will be deleted too.

    2. The second crucial part in your mapping is the @ORM\JoinColumn(onDelete="CASCADE"). On the database level this has the effect that when an entry from the category table is removed (which happens because of 1), every record in the service table that refers to the deleted category, will be deleted to (that's why the second service gets lost).

    From looking at your model I assume that changing cascade={"persist", "remove"} in your Service entity to only cascade={"persist"} will be enough (maybe you even do not need to cascade persist operations).