I have two entities
Room.php
/**
* @ORM\Table(name="room")
* @ORM\Entity(repositoryClass="Ahsio\StackBundle\Repository\RoomRepository")
*/
class Room
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// ...
/**
* @ORM\OneToMany(targetEntity="Ahsio\StackBundle\Entity\Workstation", mappedBy="room", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $workstations;
and workstation.php
/**
* @ORM\Table(name="workstation")
* @ORM\Entity(repositoryClass="Ahsio\StackBundle\Repository\Workstation")
*/
class Workstation
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Ahsio\StackBundle\Entity\Room")
* @ORM\JoinColumn(name="room_id", referencedColumnName="id", nullable=false)
*/
private $room;
// ...
I added a Room Type with a collection field for adding/updating/removing workstations
RoomType.php
class RoomType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('id', 'hidden', array(
'read_only' => true,
))
// ....
->add('workstations', 'collection', array(
'type' => new WorkstationType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;
}
// ...
}
The Workstation Type is a simple one with only two fields (id & number).
The problem is that when I’m trying to bind RoomType for an existing Room (which contains two workstations of id (1 and 2)) with The following array (Which contains only one of the two workstations):
array(4) {
["id"]=> string(1) "3"
["workstations"]=> array(1) {
[0]=> array(2) {
["id"]=> int(1)
["number"]=> int(200)
}
}
The update is well done, The workstation for id=2 is removed. But when I’m trying to remove all workstations for a given Room using:
array(4) {
["id"]=> string(1) "3"
["workstations"]=> array(0) {
}
The workstations are still there, The bind I did is well performed, here is what I got when I did a $form->getData() after binding my $form using the last given array:
object(Ahsio\StackBundle\Entity\Room)#229 (4) {
["id":protected]=> string(1) "3"
["name":protected]=> string(20) "first room (updated)"
["description":protected]=> string(39) "This first room is an old one (updated)"
["workstations":protected]=> array(0) {
}
}
So, no workstations for the updated Room. Can someone tell me why my workstations aren’t deleted when I persist this last binded Room?
Here is a part of my Controller code which I’m using to test the update …
// The Room $id is given ...
$roomArray = array(
'id' => $id,
'name' => 'first room (updated)',
'description' => 'This first room is an old one (updated)',
'workstations' => array(),
);
$form = $this->createForm(new RoomType(), $room);
$form->bind($roomArray);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($room);
$em->flush();
}
I think the setter that receives
workstationsarray is never called because the array is empty.Try to see if it is called by adding a trace.
Also, you should add the cascade=”merge” option in your workstations mapping.