Symfony Doctrine One to Many不插入外键

时间:2015-01-25 11:30:30

标签: php symfony doctrine-orm doctrine persist

我在使用一个或多个OneToMany-Childs持久化实体时遇到了烦人的问题。

我有一个“Buchung”实体,可以有多个“Einsatztage”(可以翻译成很多天的活动)

在“Buchung实体我有

/**
 * @param \Doctrine\Common\Collections\Collection $property
 * @ORM\OneToMany(targetEntity="Einsatztag", mappedBy="buchung", cascade={"all"})
 */
private $einsatztage;

$ einsatztage设置为__constructor()中的ArrayCollection()。

然后有一个“Einsatztag”实体,它有一个$ Buchung_id变量来引用“Buchung”

/**
 * @ORM\ManyToOne(targetEntity="Buchung", inversedBy="einsatztage", cascade={"all"})
 * @ORM\JoinColumn(name="buchung_id", referencedColumnName="id")
 */
private $Buchung_id;

现在如果我尝试将对象持久化到数据库,“Einsatztag”表的外键总是留空

$ buchung = new 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();

3 个答案:

答案 0 :(得分:0)

首先,您必须了解Doctrine和Symfony不能在您的实体中使用id。在Einsatztag实体中,您的属性不应被称为$ Buchung_id,因为它是buchung的实例而不是你会在那里找到一个id。

此外,在你的循环中,你将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。注意这一点,如果你没有正确使用它们,你会有一些像双重条目的行为。

SImplier,您可以使用默认的getter / setter并使用您已有的内容在关系的两侧调用它们,如下所示:

$einsatztag->set($buchung);
$buchung->addEinsatztag($einsatztag);

希望它有所帮助;)

答案 1 :(得分:0)

首先,不要在代码中使用_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是默认列名。

答案 2 :(得分:-1)

我将忽略命名问题并添加修复实际问题。

您需要在adder方法中设置调用以设置所有者。

//Buchung entity 
public function addEinsatztage($einsatztag)
{
    $this->einsatztags->add($einsatztag);
    $ein->setBuchung($this);
}

要在提交表单时调用此加法器,您需要将by_reference属性设置为false添加到表单集合字段。

以下是文档:

  

类似地,如果您正在使用CollectionType字段,其中您的基础集合数据是一个对象(如与Doctrine的ArrayCollection一样),那么如果您需要加法器和移除器,则必须将by_reference设置为false(例如addAuthor()和removeAuthor( ))被称为。

http://symfony.com/doc/current/reference/forms/types/collection.html#by-reference