If I'm not mistaken, you don't need to track Collections (associations) at all.
With the change tracking policy "notify", Doctrine will not compute change-sets for entities, but it will still compute changes in Collections. In other words, you only need to notify Doctrine about changes of _fields_, but not about _associations_. @Marco: Please correct me if I'm wrong :) -- Jasper N. Brouwer (@jaspernbrouwer) On 6 January 2015 at 23:12:20, [email protected] ([email protected]) wrote: > I use "notify" as the change tracking policy. Is it sufficient to call > onPropertyChanged() on the the owning side of the association, because this > is actually related to a database column? Or do I have to call > onPropertyChanged() on both sides? Here is my example code: > > declare(encoding='UTF-8'); > > namespace MyCompany\MyBundle\Entity; > > use Doctrine\ORM\Mapping as ORM; > use Doctrine\Common\Collections\ArrayCollection; > > /** > * @ORM\Entity > * @ORM\ChangeTrackingPolicy( "NOTIFY" ) > * @ORM\Table( name = "person" ) > */ > class Person extends Entity { > > public function __construct() { > parent::__construct(); > $this->id = null; > $this->postalAddresses = new ArrayCollection(); > } > > public function addPostalAddress( PostalAddress $postalAddress = null ) { > if( is_null( $postalAddress ) ) return $this; > if( $this->postalAddresses->contains( $postalAddress ) ) return $this; > $oldPostalAddresses = $this->postalAddresses; > $newPostalAddresses = clone( $oldPostalAddresses ); > $newPostalAddresses->add( $postalAddress ); > $this->postalAddresses = $newPostalAddresses; > $this->onPropertyChanged( 'postalAddresses', $oldPostalAddresses, > $newPostalAddresses ); > $postalAddress->setPerson( $this ); > return $this; > } > > public function removePostalAddress( PostalAddress $postalAddress = null, > Person $newPerson = null ) { > if( is_null( $postalAddress ) ) return $this; > if( !( $this->postalAddresses->contains( $postalAddress ) ) ) return > $this; > if( $newPerson == $this ) return $this; > $oldPostalAddresses = $this->postalAddresses; > $newPostalAddresses = clone( $oldPostalAddresses ); > $newPostalAddresses->removeElement( $postalAddress ); > $this->postalAddresses = $newPostalAddresses; > $this->onPropertyChanged( 'postalAddresses', $oldPostalAddresses, > $newPostalAddresses ); > $postalAddress->setPerson( $newPerson ); > return $this; > } > > /** > * @ORM\Id > * @ORM\Column( name = "id", type = "integer" ) > * @ORM\GeneratedValue( strategy = "SEQUENCE" ) > * @var int > */ > protected $id = null; > > /** > * @ORM\OneToMany( targetEntity = "PostalAddress", mappedBy = "person" ) > * @var Doctrine\Common\Collections\ArrayCollection > */ > protected $postalAddresses = null; > } > > > /** > * @ORM\Entity > * @ORM\ChangeTrackingPolicy( "NOTIFY" ) > * @ORM\Table( name = "postal_address" ) > */ > class PostalAddress extends Entity { > > public function __construct( Person $person ) { > parent::__construct(); > $this->id = null; > $this->setPerson( $person ); > } > > public function setPerson( Person $newPerson = null ) { > if( $this->person == $newPerson ) return $this; > $oldPerson = $this->person; > $this->person = $newPerson; > $this->onPropertyChanged( 'person', $oldPerson, $newPerson ); > if( !is_null( $oldPerson ) ) $oldPerson->removePostalAddress( $this, > $newPerson ); > if( !is_null( $newPerson ) ) $newPerson->addPostalAddress( $this ); > return $this; > } > > /** > * @ORM\Id > * @ORM\Column( name = "id", type = "integer" ) > * @ORM\GeneratedValue( strategy = "SEQUENCE" ) > * @var int > */ > protected $id = null; > > /** > * @ORM\ManyToOne( targetEntity = "Person", inversedBy = > "postalAddresses" ) > * @ORM\JoinColumn( name = "person_id", referencedColumnName = "id", > nullable = false ); > * @var Person > */ > protected $person = null; > } > > ?> > > It seems that it works either way but what is the intended (i.e. correct) > way to go? If it is sufficient to do the notification at the owning side, > the getters and setters for the ArrayCollection can be simplified and a > costly clone of the ArrayCollection can be avoided. Instead of my current > code the following snippet would be enough: > public function addPostalAddress( PostalAddress $postalAddress = null ) { > if( is_null( $postalAddress ) ) return $this; > if( $this->postalAddresses->contains( $postalAddress ) ) return $this; > $this->postalAddresses->add( $postalAddress ); > $postalAddress->setPerson( $this ); > return $this; > } > This seems to work, too, but will it do so in future versions of Doctrine? -- You received this message because you are subscribed to the Google Groups "doctrine-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/doctrine-user. For more options, visit https://groups.google.com/d/optout.
