How to use the cascade option in Doctrine2 to have

2019-02-16 17:39发布

问题:

Can someone explain me this:

$user = new User();

/* why do I have to call Entity Comment while trying to insert into db?  */
$myFirstComment = new Comment();

$user->addComment($myFirstComment);

$em->persist($user);
$em->persist($myFirstComment);
$em->flush();

Why do I have to call Entity Comment while trying to insert into db?

I have cascade for that.

  1. Does this mean that if I have 50 relation in User Entity with other entities I have to call each relation manually when trying to update/insert/delete?
  2. Why does cascade exist if I have to do all manually?

If I have to call all that relation manually it is kind of stupid to use Doctrine at all.

I do not get this. Any help is appreciated.

This is connected with this: doctrine 2, unable to insert to database when relation is present

回答1:

To have Doctrine automatically handle the persistence of your User#comments property you have to set cascade to the "persist" operation.

The cascade ( persist, remove , merge, all ) option gives you the ability to ommit ...

$em->persist($myFirstComment);

... if you set it correctly on your inverse side of a bidirectional relation for example. It can also automatically remove User#comments if you remove a User entity with cascade "remove" !

example:

/**
 * Bidirectional - One-To-Many (INVERSE SIDE)
 *
 * @OneToMany(targetEntity="Comment", mappedBy="author", cascade={"persist", "remove"})
 */
private $comments;

Read more on Association mapping and cascade in the Transistive Persistence / Cascade Options chapter of the documentation.

Please remember:

Doctrine will only check the owning side of an association for changes.

Changes made only to the inverse side of an association are ignored. Make sure to update both sides of a bidirectional association (or at least the owning side, from Doctrine’s point of view)

  • OneToMany associations are never the owning side.
  • The inverse side has to use the mappedBy attribute of the OneToOne, OneToMany, or ManyToMany mapping declaration. The mappedBy attribute contains the name of the association-field on the owning side
  • The owning side has to use the inversedBy attribute of the OneToOne, ManyToOne, or ManyToMany mapping declaration. The inversedBy attribute contains the name of the association-field on the inverse-side.
  • ManyToOne is always the owning side of a bidirectional association.
  • OneToMany is always the inverse side of a bidirectional association.

Furthermore:

you only have to call persist if you create a new root entity ( i.e. $user = new User() ) which is not already managed by doctrine ( and you don't have to call persist on $myFirstComment in your example if you have set the cascade option correctly ).

Otherwise you only have to call flush if the entity hasn't for some reason been detached.