Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete an item from oneToMany relationship

I have the following Gallery entity

class Gallery {     /**      * @var integer      *      * @ORM\Column(name="id", type="integer")      * @ORM\Id      * @ORM\GeneratedValue(strategy="AUTO")      */     private $id;      /**      * @var ArrayCollection      * @ORM\OneToMany(targetEntity="Tessa\GalleryBundle\Entity\Photo", mappedBy="gallery", cascade={"persist", "remove"})      */     private $photos;      /* ... */ } 

This gallery is linked with a manyToOne relationship to a PointOfInterest entity. Here is the declaration

class PointOfInterest {  /* ... */  /**  * @ORM\ManyToOne(targetEntity="Tessa\GalleryBundle\Entity\Gallery", cascade={"persist", "remove"})  * @ORM\JoinColumn(nullable=false)  */ private $gallery;  /* ... */ 

I also use a Form to update the PointOfInterest entity. Here is the form declaration

public function buildForm(FormBuilderInterface $builder, array $options) {     $builder             ->add('name',           'text')             ->add('gallery',        new GalleryType())        ; } 

and the GalleryType declaration.

public function buildForm(FormBuilderInterface $builder, array $options) {     $builder         ->add('photos', 'collection', array('type'          => new PhotoType(),                                             'required'      => false,                                             'allow_add'     => true,                                             'allow_delete'  => true,                                             'by_reference'  => false                                             ))     ; } 

When I edit the PoI I can add photos to the gallery without problem, but I can't delete anything.

I tried to hook on gallery PreUpdate, but it is never called. I printed output in removePhotos method of Gallery entity, and the photos are removed from the gallery. I then suspect the Gallery to never be persisted.

Here is the code when I persist the PoI after editing.

private function handleForm($elem, $is_new) {     $form = $this->createForm(new CircuitType, $elem);      $request = $this->get('request');     if ($request->getMethod() == 'POST') {         $form->bind($request);          if ($form->isValid()) {             $em = $this->getDoctrine()->getManager();             $em->persist($elem);             $em->flush();              return $this->redirect($this->generateUrl('tessa_circuit_index'));         }     }      return $this->render('TessaUserBundle:Circuits:add.'.'html'.'.twig',         array(             'form' => $form->createView(),             'is_new' => $is_new,         )); } 
like image 639
tomahh Avatar asked Apr 24 '13 16:04

tomahh


People also ask

How do you delete a one to many relationship in JPA?

If an entity that is the target of the relationship is removed from the relationship (by setting the relationship to null or removing the entity from the relationship collection), the remove operation will be applied to the entity being orphaned. The remove operation is applied at the time of the flush operation.

How do I delete a child entity from one to many relationship?

Then how do we delete the child entity from the database? Hibernate does that automatically when you set the orphanRemoval attribute of the @OneToMany annotation to true and the cascade attribute to CascadeType. ALL , it auto delete child entities while deleting parent. CascadeType.

What is orphan delete?

As stated earlier, its usage is to delete orphaned entities from the database. An entity that is no longer attached to its parent is the definition of being an orphan. In our case, an OrderRequest has a collection of LineItem objects where we use the @OneToMany annotation to identify the relationship.


1 Answers

There is article in Symfony2 cookbook about handling this type of situation. As you have OneToMany relationship, you have to remove related objects manually in controller.

Edit: Or you can make use of Doctrine's orphan removal feature.

class Gallery {     //...          /**      * @ORM\OneToMany(targetEntity="Photo", mappedBy="gallery", cascade={"persist", "remove"}, orphanRemoval=true)      */     private $photos;      //...      public function removePhotos($photo)     {         $this->photos->remove($photo);         $photo->setGallery(null);     } } 
like image 67
gatisl Avatar answered Sep 20 '22 15:09

gatisl