18/02/2017 - DOCTRINE, SYMFONY
Bu yazıda doctrine'nin cascade={"persist"}
özelliğinin nerede ve ne zaman kullanılacağını veya kullanılmayacağını öğreneceğiz.
İlişkilerin her iki tarafında ("inverse" ve "owning") cascade={"persist"}
özelliğinin kullanılması tavsiye edilmez ama kullanırsanız da problem olmaz. Genel olarak "inverse" tarafta kullanılır, yani mappedBy
özelliğinin tanımlandığı taraf. Buna "parent/independent" tarafta diyebilirsiniz. Elimizde League 1-n Team (OneToMany) şeklinde bir ilişki olduğunu varsayarsak, "inverse" taraf League olacaktır.
class League
{
/**
* @ORM\OneToMany(targetEntity="Team", mappedBy="league")
*/
private $teams;
public function __construct()
{
$this->teams = new ArrayCollection();
}
}
class Team
{
/**
* @ORM\ManyToOne(targetEntity="League", inversedBy="teams")
* @ORM\JoinColumn(name="league_id", referencedColumnName="id", nullable=false)
*/
private $league;
}
Bu gibi durumlarda, persist işlemi her iki entity üzerinde manuel olarak yapıIır.
League: @ORM\OneToMany(targetEntity="Team", mappedBy="league")
Team: @ORM\ManyToOne(targetEntity="League", inversedBy="teams")
$league = new League();
$team = new Team();
// add or set Team in League
// add or set League in Team
$entityManager->persist($league);
$entityManager->persist($team);
$entityManager->flush();
Bu gibi durumlarda, persist işlemi sadece League üzerinde manuel olarak yapıIır. Team üzerinde manuel olarak işlem yapmaya gerek yok ama yaparsanızda herhangi bir problem çıkmaz.
League: @ORM\OneToMany(targetEntity="Team", mappedBy="league", cascade={"persist"})
Team: @ORM\ManyToOne(targetEntity="League", inversedBy="teams")
$league = new League();
$team = new Team();
// add or set Team in League
// add or set League in Team
$entityManager->persist($league);
$entityManager->persist($team); // Unnecessary
$entityManager->flush();
Bu gibi durumlarda, persist işlemi sadece Team üzerinde manuel olarak yapıIır. League üzerinde manuel olarak işlem yapmaya gerek yok ama yaparsanızda herhangi bir problem çıkmaz.
League: @ORM\OneToMany(targetEntity="Team", mappedBy="league")
Team: @ORM\ManyToOne(targetEntity="League", inversedBy="teams", cascade={"persist"})
$league = new League();
$team = new Team();
// add or set Team in League
// add or set League in Team
$entityManager->persist($league); // Unnecessary
$entityManager->persist($team);
$entityManager->flush();
Bu gibi durumlarda, persist işlemi ya League ya da Team üzerinde manuel olarak yapıIır. Her ikisi üzerinde manuel olarak işlem yapmaya gerek yok ama yaparsanızda herhangi bir problem çıkmaz.
League: @ORM\OneToMany(targetEntity="Team", mappedBy="league", cascade={"persist"})
Team: @ORM\ManyToOne(targetEntity="League", inversedBy="teams", cascade={"persist"})
$league = new League();
$team = new Team();
// add or set Team in League
// add or set League in Team
$entityManager->persist($league); // Either this
$entityManager->persist($team); // or this
$entityManager->flush();
Persist işlemini cascade={"persist"}
özelliğini kullanan entity üzerinde yapmak yeterli olacaktır, o nedenle diğer entity es geçilebilir ama, aynı ilişkide her iki entity için cascade={"persist"}
özelliği ayarlanırsa, her iki entity üzerinde persist işlemi yapabilirsiniz.
Persist işlemi yaparken, şu şekilde bir hata mesajı alabilirsiniz (genelde ilişkilerde cascade={"persist"}
özelliğinin kullanmayı unuttuğunuzda olur): A new entity was found through the relationship 'League#teams' that was not configured to cascade persist operations for entity: Team@000000006fefb0fd00007fa33b3653bf. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ORM\...(..,cascade={"persist"}).
. Mesajdaki bilinmeyen (unknown) diye geçen entity Team olanıdır. Sizden istenen, ya $entityManager->persist($team);
komutunun çalıştırılması, ya da o andaki persist işleminin yapıldığı League üzerinde cascade={"persist"}
özelliğinin ektinleştirilmesidir.
# As you can see below, our mapping is missing cascade property
League: @ORM\OneToMany(targetEntity="Team", mappedBy="league")
Team: @ORM\ManyToOne(targetEntity="League", inversedBy="teams")
$league = new League();
$team = new Team();
// add or set Team in League
// add or set League in Team
$entityManager->persist($league);
// $entityManager->persist($team); // -> You forgot to use this so either enable it or just add cascade={"persist"} to League entity
$entityManager->flush();