У меня возникли досадные проблемы с сохранением сущности с одним или несколькими OneToMany-Childs.
У меня есть сущность «Buchung», которая может иметь несколько «Einsatztage» (может быть переведено на событие с несколькими днями)
В «Бучунг сущности у меня есть
/**
* @param \Doctrine\Common\Collections\Collection $property
* @ORM\OneToMany(targetEntity="Einsatztag", mappedBy="buchung", cascade={"all"})
*/
private $einsatztage;
$ einsatztage устанавливается в ArrayCollection () в __constructor ().
Затем существует сущность Einsatztag, которая имеет переменную $ Buchung_id для ссылки на Buchung.
/**
* @ORM\ManyToOne(targetEntity="Buchung", inversedBy="einsatztage", cascade={"all"})
* @ORM\JoinColumn(name="buchung_id", referencedColumnName="id")
*/
private $Buchung_id;
Теперь, если я пытаюсь сохранить объект в базе данных, внешний ключ таблицы «Einsatztag» всегда остается пустым
$ buchung = новый Buchung ();
$buchung->setEvent( $r->request->get("event_basis"));
$buchung->setStartDate(new \DateTime($r->request->get("date_from")));
$buchung->setEndDate(new \DateTime($r->request->get("date_to")));$von = $r->request->get("einsatz_von");
$bis = $r->request->get("einsatz_bis");
$i = 0;
foreach($von as $tag){
$einsatztag = new Einsatztag();
$einsatztag->setNum($i);
$einsatztag->setVon($von[$i]);
$einsatztag->setBis($bis[$i]);
$buchung->addEinsatztage($einsatztag);
$i++;
}
$em = $this->getDoctrine()->getManager();
$em->persist($buchung);
foreach($buchung->getEinsatztage() as $e){
$em->persist($e);
}
$em->flush();
Во-первых, вы должны понимать, что Doctrine и Symfony не работают с идентификаторами внутри ваших сущностей. В сущности Einsatztag ваше свойство не должно называться $ Buchung_id, так как это экземпляр buchung, а не идентификатор, который вы там найдете.
Более того, вы добавляете Einsatztag в Buchung. Но вы обрабатываете обратный набор?
Я делаю это таким образом, чтобы всегда полностью изменить набор / добавление сущностей.
Einsatztag
public function setBuchung(Buchung $pBuchung, $recurs = true){
$this->buchung = $pBuchung;
if($recurs){
$buchung->addEinsatztag($this, false);
}
}
Buchung
public function addEinsatztag(Einsatztag $pEinsatztag, $recurs = true){
$this->einsatztages[] = $pEinsatztag;
if($recurs){
$pEinsatztag->setBuchung($this, false);
}
}
Потом, когда позвонишь
$buchung->addEinsatztag($einsatztag);
Или же
$einsatztag->set($buchung);
Отношение будет установлено с обеих сторон, и ваш FK будет установлен. Позаботьтесь об этом, вы будете вести себя как двойные записи, если вы не используете их должным образом.
Проще говоря, вы можете использовать метод получения / установки по умолчанию и вызывать их по обе стороны вашего отношения, используя то, что у вас уже есть, например:
$einsatztag->set($buchung);
$buchung->addEinsatztag($einsatztag);
Надеюсь, это помогло;)
Прежде всего, не используйте _id
свойства в вашем коде. Будь как будет $buchung
, Если вы хотите это в базе данных, сделайте это в аннотации. И это также причина, почему это не работает. Вы сопоставляете с buchung
, но ваша собственность $Buchung_id
<?php
/** @ORM\Entity **/
class Buchung
{
// ...
/**
* @ORM\OneToMany(targetEntity="Einsatztag", mappedBy="buchung")
**/
private $einsatztage;
// ...
}
/** @ORM\Entity **/
class Einsatztag
{
// ...
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="einsatztage")
* @JoinColumn(name="buchung_id", referencedColumnName="id")
**/
private $buchung;
// ...
}
Вам не нужно писать @JoinColumn
, так как <propertyname>_id
будет имя столбца по умолчанию.
Я собираюсь игнорировать проблему именования и добавить исправление к актуальной проблеме.
Вы должны иметь в методе сумматора вызов, чтобы установить владельца.
//Buchung entity
public function addEinsatztage($einsatztag)
{
$this->einsatztags->add($einsatztag);
$ein->setBuchung($this);
}
И чтобы этот сумматор вызывался при отправке формы, вам нужно добавить в поле коллекции форм by_reference
свойство установлено в false
,
Вот документация:
Точно так же, если вы используете поле CollectionType, где ваши базовые данные коллекции являются объектом (как в ArrayCollection Doctrine), тогда by_reference должно быть установлено в false, если вам нужны сумматор и съемник (например, addAuthor () и removeAuthor ()) для называться.
http://symfony.com/doc/current/reference/forms/types/collection.html#by-reference