You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 5:未设by_reference=false时映射端多对多关系无法持久化

Symfony 5多对多关系表单持久化问题

背景

我正在开发一个Symfony 5应用,其中实体InventaireActif与TypeActif存在多对多(ManyToMany)关系。通过Symfony表单管理该关系时出现问题。

问题

在TypeActif的表单中添加InventaireActif实体时,除非在表单构建器中设置'by_reference' => false选项,否则关系无法持久化到数据库。我希望不依赖该选项实现正确的持久化效果。

实体配置

InventaireActif.php

/**
 * @ORM\ManyToMany(targetEntity=TypeActif::class, inversedBy="lesActifs")
 */
private $lesTypesActifs;

public function __construct()
{
    $this->lesTypesActifs = new ArrayCollection();
    // ... 其他初始化代码 ...
}

/**
 * @return Collection<int, TypeActif>
*/
public function getLesTypesActifs(): Collection
    {
        return $this->lesTypesActifs;
    }

    public function addLesTypesActif(TypeActif $lesTypesActif): self
    {
        if (!$this->lesTypesActifs->contains($lesTypesActif)) {
            $this->lesTypesActifs[] = $lesTypesActif;
        }

        return $this;
    }

    public function removeLesTypesActif(TypeActif $lesTypesActif): self
    {
        $this->lesTypesActifs->removeElement($lesTypesActif);

        return $this;
    }

TypeActif.php

/**
 * @ORM\ManyToMany(targetEntity=InventaireActif::class, mappedBy="lesTypesActifs")
 */
private $lesActifs;

public function __construct()
{
    $this->lesActifs = new ArrayCollection();
    // ... 其他初始化代码 ...
}

public function getLesActifs(): Collection
{
    return $this->lesActifs;
}

public function addLesActif(InventaireActif $lesActif): self
{
    if (!$this->lesActifs->contains($lesActif)) {
        $this->lesActifs[] = $lesActif;
        $lesActif->addLesTypesActif($this);
    }
    return $this;
}

public function removeLesActif(InventaireActif $lesActif): self
{
    if ($this->lesActifs->removeElement($lesActif)) {
        $lesActif->removeLesTypesActif($this);
    }
    return $this;
}

表单配置(TypeActifType.php)

public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder
        // ... 其他字段 ...
        ->add('lesActifs', EntityType::class, [
            'required' => false,
            'class' => InventaireActif::class,
            'choice_label' => 'libelle',
            // 'by_reference' => false,
            'multiple' => true,
            'query_builder' => function (InventaireActifRepository $repo) {
                return $repo->lesActifsReformesSortedASC();
            },
        ]);
}

控制器新增路由(TypeActifController.php)

public function new(Request $request, TypeActifRepository $typeActifRepository, EntityManagerInterface $entityManager): Response
    {
        $typeActif = new TypeActif();
        $form = $this->createForm(TypeActifType::class, $typeActif);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $typeActifRepository->add($typeActif, true);

            return $this->redirectToRoute('app_type_actif_index', [], Response::HTTP_SEE_OTHER);
        }

        return $this->renderForm('type_actif/new.html.twig', [
            'type_actif' => $typeActif,
            'form' => $form,
        ]);
    }

与by_reference相关的问题

  • 取消注释'by_reference' => false时,表单正常工作,多对多关系按预期更新。
  • 但我希望避免使用'by_reference' => false。不设置该选项时,通过TypeActif表单添加InventaireActif实体的更改无法持久化。

已尝试的解决方法

  • 确保两个实体中的add和remove方法同步。
  • 检查Doctrine配置和注解。

预期行为

通过TypeActif表单添加InventaireActif实体时,无需设置'by_reference' => false,更改即可保存到数据库。

当前行为

不设置'by_reference' => false时,更改无法持久化。无错误提示,日志也无异常信息。


内容的提问来源于stack exchange,提问作者Meyo GIT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:53:22