Symfony OneToMany更新而不是插入

时间:2018-08-22 15:55:04

标签: php symfony symfony-forms symfony-3.1

我是Symfony的初学者。

我的表格有一个奇怪的问题。

我有2个实体:Proposal_Lsi和Lsi_Beams。一个提议可以有多个提议,但是一个提议只能有一个提议。我以为我应该使用OneToMany / ManyToOne关系,而我拥有的一面是梁一,相反的一面是提案。

我遵循https://symfony.com/doc/3.1/form/form_collections.html上有关表格收集的官方指南。

一切都很好,我可以提交带有多个光束的新提案,并且所有提案都正确存储在数据库中。

每当我尝试向提案中添加新的梁时,就会出现问题:系统会覆盖(更新查询)现有的梁(从数据库中的第一个梁开始),而不是添加新的(插入)查询)。

我想念什么?

如果可以的话,这是我的一些代码。

投标类别:

class Proposal_lsi{
/**
* @ORM\OneToOne(targetEntity="Emir2Bundle\Entity\Proposal", inversedBy="proposal_lsi")
* @ORM\JoinColumn(name="proposal", referencedColumnName="id")
* @ORM\Id
*/  
private $proposal;

/**
* @ORM\OneToMany(targetEntity="Emir2Bundle\Entity\Lsi_beams", mappedBy="proposal_lsi")
*/  
private $lsi_beams;

...

/**
 * Add lsiBeam
 *
 * @param \Emir2Bundle\Entity\Lsi_beams $lsiBeam
 * @return Proposal_lsi
 */
public function addLsiBeam(\Emir2Bundle\Entity\Lsi_beams $lsiBeam)
{
    $lsiBeam->setProposalLsi($this);
    $this->lsi_beams[] = $lsiBeam;

    return $this;
}

}

光束等级:

class Lsi_beams{
/**
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
* @ORM\ManyToOne(targetEntity="Emir2Bundle\Entity\Proposal_lsi", inversedBy="lsi_beams", cascade={"persist"})
* @ORM\JoinColumn(name="proposal_lsi", referencedColumnName="proposal", nullable=false)
*/
private $proposal_lsi;

...
}

以及控制器中的表单:

$form = $this->createFormBuilder($proposallsi)
        ->setAction($this->generateUrl('lsi_submission', array('id' => $id)))
        ->setMethod('POST')
        ->add('lsi_beams', CollectionType::class, array(
            'entry_type'    => LsiBeamsType::class,
            'allow_add'     => true,
            'allow_delete'      => true,
            'prototype'     => true,
            'by_reference'  => false
            )
        )
...

我做错了什么?让我知道您是否需要更多代码。

感谢您的回复!

1 个答案:

答案 0 :(得分:0)

注意:

  1. 使用学说ArrayCollection更好地跟踪馆藏
  2. cascade={"persist"}放在关联的反面(您有mappedBy的地方)
  3. 保持实体名称为单数(例如Lsi_beam而不是Lsi_beams
  4. 保持清晰明确的命名策略。请勿在类和属性名称中使用undescores(例如,使用$ lsiBeams代替$ lsi_beams)

ProposalLsi

use Doctrine\Common\Collections\ArrayCollection;

class ProposalLsi
{
    /**
    * @ORM\OneToMany(targetEntity="LsiBeam", mappedBy="proposalLsi", cascade={"persist"})
    */  
    private $lsiBeams;

    public function __construct()
    {
        $this->lsiBeams = new ArrayCollection();
    }

    public function addLsiBeam(LsiBeams $lsiBeam)
    {
        if ($this->lsiBeams->contains($lsiBeam)) {

            return;
        } else {

            $lsiBeam->setProposalLsi($this);
            $this->lsiBeams->add($lsiBeam);
        }

        return $this;
    }

    public function removeLsiBeam(LsiBeams $lsiBeam)
    {
        if (!$this->lsiBeams->contains($lsiBeam)) {

            return;
        } else {

            $lsiBeam->setProposalLsi(null);
            $this->lsiBeams->removeElement($lsiBeam);
        }

        return $this;
    }
}

LsiBeam

class LsiBeam
{
    /**
    * @ORM\ManyToOne(targetEntity="ProposalLsi", inversedBy="lsiBeams")
    */
    private $proposalLsi;

    public function setProposalLsi(?ProposalLsi $proposalLsi)
    {
        $this->proposalLsi = $proposalLsi;
    }

}