Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2.0 vs 2.1 cascade remove OneToMany

Tags:

doctrine-orm

Hello I have problem when trying to cascade remove entities in OneToMany relations. After a few hours of debugging I tried to downgrade the doctrine from the latest 2.1.2 to 2.0.2 and It suddenly starts working.

Imagin two entities Company and Address in relation 1:N.

/**
 * @Entity
 */
class Company extends Entity
{

 /**
  * @var integer
  * @id @Column(type="integer")
  * @generatedValue
  */
 private $id;

 /**
  * @var Collection
  * @OneToMany(targetEntity="Address",mappedBy="company", cascade={"persist","remove"})
  */
 private $addresses;
}



/**
 * @Entity
 */
class Address extends Entity
{

 /**
  * @var integer
  * @id @Column(type="integer")
  * @generatedValue
  */
 private $id;

 /**
  * @var Company
  * @ManyToOne(targetEntity="Company", inversedBy="addresses")
  * @JoinColumn(name="company_id", referencedColumnName="id",nullable=false)
  */
 private $company;
}

when I try to remove the entity Company, I would like the assigned addresses will be removed as well.

$em->remove($company);
$em->flush();

In doctrine 2.1.2 the deletion of addresses is not performed so the integrity constraint fails. In version 2.0.2 there it works perfectly. Wierd thing on it is, if I use EntityAudit extension https://github.com/simplethings/EntityAudit the LogRevisionListener is corretly versioning the addresses entities (set them revtype = DEL) in doctrine 2.1.2 (of course in 2.0.2 as well) but the UnitOfWork is not removing it.

Is there any difference how to handle cascade removing in 2.0.2 and in 2.1.2?

Thank you very much

like image 807
stefi Avatar asked Oct 14 '11 11:10

stefi


3 Answers

Try using this on the addresses attribute of your Company Class

@OneToMany(targetEntity="Address",mappedBy="company", 
cascade={"persist"}, orphanRemoval=true)
like image 111
Entea Avatar answered Nov 03 '22 21:11

Entea


I had the same problem... Relations were added or updated, but not deleted, even if I had cascade: [persist, remove].

I found out that I didn't need the "remove" attribute in "cascade", but I had to add the orphanRemoval: true.

I was going crazy, you made my day!

like image 3
Tiois Avatar answered Nov 03 '22 22:11

Tiois


I have met the same problem and i have solved him with that code :

$em->remove($object);
$em->flush();
$em->remove($user);
$em->flush();

Maybe you can use a findAll on your company for the addresses and remove this with a foreach like that :

// Return all the addresses of the company
$addresses = $em->getRepository(...)->findAllAddressesByCompany($company);
$em->remove($company);
foreach ($address in $addresses)
{
    $em->remove($address);
}

That's not a very good method but for now, that's all I've found.

like image 1
Naelyth Avatar answered Nov 03 '22 22:11

Naelyth