RemoveElement() and clear() doesn't work in doctrine 2 with array collection property?

"YOU AND THE ART OF ONLINE DATING" is the only product on the market that will take you step-by-step through the process of online dating, provide you with the resources to help ensure success. Get it now!

I do something similar in a project with Events which have participants not unlike your User/Country relationship. I will just lay out the process and you can see if there's anything you are doing differently On the Participant entity ManyToOne(targetEntity="Event", inversedBy="participants", fetch="LAZY") * @JoinColumn(name="event_id", referencedColumnName="id", nullable="TRUE") * @var Event */ protected $event On the Event entity: OneToMany(targetEntity="Participant", mappedBy="event") * @var \Doctrine\Common\Collections\ArrayCollection */ protected $participants Also in Event#__constructor I initialize like this: $this->participants = new \Doctrine\Common\Collections\ArrayCollection() Here is how I update an event: public function update(Event $event, Event $changes) { // Remove participants $removed = array(); foreach($event->participants as $participant) { if(!$changes->isAttending($participant->person)) { $removed = $participant; } } foreach($removed as $participant) { $event->removeParticipant($participant); $this->em->remove($participant); } // Add new participants foreach($changes->participants as $participant) { if(!$event->isAttending($participant->person)) { $event->addParticipant($participant); $this->em->perist($participant); } } $event->copyFrom($changes); $event->setUpdated(); $this->em->flush(); } The methods on the Event entity are: public function removeParticipant(Participant $participant) { $this->participants->removeElement($participant); $participant->unsetEvent(); } public function addParticipant(Participant $participant) { $participant->setEvent($this); $this->participants = $participant; } The methods on the Participant entity are: public function setEvent(Event $event) { $this->event = $event; } public function unsetEvent() { $this->event = null; } UPDATE : isAttending method Checks if the given person is a * participant of the event * * @param Person $person * @return boolean */ public function isAttending(Person $person) { foreach($this->participants as $participant) { if($participant->person->id == $person->id) return true; } return false; }.

I do something similar in a project with Events which have participants not unlike your User/Country relationship. I will just lay out the process and you can see if there's anything you are doing differently. On the Participant entity /** * @ManyToOne(targetEntity="Event", inversedBy="participants", fetch="LAZY") * @JoinColumn(name="event_id", referencedColumnName="id", nullable="TRUE") * @var Event */ protected $event; On the Event entity: /** * @OneToMany(targetEntity="Participant", mappedBy="event") * @var \Doctrine\Common\Collections\ArrayCollection */ protected $participants; Also in Event#__constructor I initialize like this: $this->participants = new \Doctrine\Common\Collections\ArrayCollection(); Here is how I update an event: public function update(Event $event, Event $changes) { // Remove participants $removed = array(); foreach($event->participants as $participant) { if(!$changes->isAttending($participant->person)) { $removed = $participant; } } foreach($removed as $participant) { $event->removeParticipant($participant); $this->em->remove($participant); } // Add new participants foreach($changes->participants as $participant) { if(!$event->isAttending($participant->person)) { $event->addParticipant($participant); $this->em->perist($participant); } } $event->copyFrom($changes); $event->setUpdated(); $this->em->flush(); } The methods on the Event entity are: public function removeParticipant(Participant $participant) { $this->participants->removeElement($participant); $participant->unsetEvent(); } public function addParticipant(Participant $participant) { $participant->setEvent($this); $this->participants = $participant; } The methods on the Participant entity are: public function setEvent(Event $event) { $this->event = $event; } public function unsetEvent() { $this->event = null; } UPDATE: isAttending method /** * Checks if the given person is a * participant of the event * * @param Person $person * @return boolean */ public function isAttending(Person $person) { foreach($this->participants as $participant) { if($participant->person->id == $person->id) return true; } return false; }.

I'm adapting this to my project. One quick question though... I'm passing my update function an array ($_POST actually) how do you set the event and where so that you pass it as an object? I guess that's much "healthier" for doctrine, right?

Is there a way to "automagically" feed the object with the array? – la_f0ka Jun 24 at 18:44 I would avoid "automagical" object creation from $_POST. The reason I do it like this is that the event input is complex and requires a lot of validation.

I have a class (factory) that takes an array (e.g. , $_POST) and creates an Event object. Once I have validated that object I can just save it if it is "new", or use it to update an existing event as above. You don't need to go to this extreme if your input is simple and only requires simple validation.

Just make sure you always validate input. – rojoca Jun 24 at 20:04 with your help and example I was able to overcome my biggest problem with Doctrine 2, I was really stuck with this and now my code even looks prettier. Thanks a lot!

– la_f0ka Jun 25 at 22:05.

Initial answer You need to set the countries field in your entity as remove cascade. For example, on a bidirectional one to many relationship: class Entity { /** * * @OneToMany(targetEntity="Country", mappedBy="entity", cascade={"remove"}) */ private $countries; } This way, when saving your entity, doctrine will also save changes in collections attached to your entity (such as countries). Otherwise you have to explicitly remove the countries you want to remove before flushing, e.g. $this->em()->remove($aCountry); This is also valid for persist, merge and detach operations.

More information here.

Faken check the edit, it's already set as you suggested, however it doesn't work. – la_f0ka Jun 24 at 1:09 see my edit. – faken Jun 24 at 1:30 @faken well I tried that too and I still don't seem to get these damn countries to be removed – la_f0ka Jun 24 at 1:53 I think you have to recreate or update the schema after making these changes on the entities.

Did you do that? (Beware of just "updating" the schema, it usually trashes the DB; it's probably better to delete the tables and recreate them) – faken Jun 24 at 2:10 yes, I did that too. It's been a pretty long and frustrating day and everything that was supposed to work hasn't worked.Do you have any CRUD examples where there's an update for a record with a OneToMany relationship?

I haven't really found anything good online on that. – la_f0ka Jun 24 at 3:07.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions