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, )); }
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.
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.
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.
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With