Symfony4 FOSRestBundle 尝试保留 ManyToMany SQL 语法错误

Symfony4 FOSRestBundle try to persist ManyToMany SQL syntax error

我收到 SQL 语法错误:

An exception occurred while executing 'INSERT INTO group (name) VALUES (?)' with params [\"Entwickler\"]:\n\nSQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'group (name) VALUES ('Entwickler')' at line 1

当我尝试保留具有多对多关系的实体时。

场景

我有一个名为 folder 的实体和一个名为 group 的实体。这些实体之间是多对多的关系,因为一个组可以有多个文件夹,一个文件夹可以有多个组。

已有 1 个文件夹 ID 为 1。现在我想创建一个组,想把id为1的文件夹加入这个组

组实体

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\GroupRepository")
 */
class Group
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Folder", inversedBy="groups")
     * @ORM\JoinTable(
     *  name="group_folder",
     *  joinColumns={
     *      @ORM\JoinColumn(name="group_id", referencedColumnName="id")
     *  },
     *  inverseJoinColumns={
     *      @ORM\JoinColumn(name="folder_id", referencedColumnName="id")
     *  }
     * )
     */
    private $folder;

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

    public function getId()
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return Collection|Folder[]
     */
    public function getFolder(): Collection
    {
        return $this->folder;
    }

    public function addFolder(Folder $folder): self
    {
        if (!$this->folder->contains($folder)) {
            $this->folder[] = $folder;
        }

        return $this;
    }

    public function removeFolder(Folder $folder): self
    {
        if ($this->folder->contains($folder)) {
            $this->folder->removeElement($folder);
        }

        return $this;
    }
}

文件夹实体

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="App\Repository\FolderRepository")
 */
class Folder
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=45)
     * @Assert\NotBlank()
     */
    private $name;

    /**
     * @var Secret[]
     * @ORM\OneToMany(targetEntity="App\Entity\Secret", mappedBy="folder")
     */
    private $secrets;

    /**
     * @var Folder[]
     *
     * @ORM\OneToMany(targetEntity="Folder", mappedBy="parent")
     */
    private $children;

    /**
     * @var Folder
     *
     * @ORM\ManyToOne(targetEntity="Folder", inversedBy="children")
     * @ORM\JoinColumn(name="parent", referencedColumnName="id")
     */
    private $parent;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Group", mappedBy="folder")
     */
    private $groups;

    public function __construct()
    {
        $this->children = new ArrayCollection();
        $this->secrets = new ArrayCollection();
        $this->groups = new ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @return Secret[]|ArrayCollection
     */
    public function getSecrets()
    {
        return $this->secrets;
    }

    /**
     * @return Folder[]|ArrayCollection
     */
    public function getChildren()
    {
        return $this->children;
    }

    /**
     * @param Folder $children
     */
    public function addChildren($children)
    {
        $this->children[] = $children;
        $children->setParent($this);
    }

    /**
     * @return Folder
     */
    public function getParent()
    {
        return $this->parent;
    }

    /**
     * @param Folder $parent
     */
    public function setParent($parent)
    {
        $this->parent = $parent;
    }

    /**
     * @return Collection|Group[]
     */
    public function getGroups(): Collection
    {
        return $this->groups;
    }

    public function addGroup(Group $group): self
    {
        if (!$this->groups->contains($group)) {
            $this->groups[] = $group;
            $group->addFolder($this);
        }

        return $this;
    }

    public function removeGroup(Group $group): self
    {
        if ($this->groups->contains($group)) {
            $this->groups->removeElement($group);
            $group->removeFolder($this);
        }

        return $this;
    }
}

GroupType 形式

<?php

namespace App\Form;

use App\Entity\Folder;
use App\Entity\Group;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class GroupType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('folder', EntityType::class, [
                'class' => Folder::class,
                'multiple' => true
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Group::class,
        ]);
    }
}

我将 POST 请求发送到

的控制器操作
/**
 * @param Request $request
 * @return View
 *
 * @Rest\Post("/api/groups", name="api_group_create")
 */
public function CreateGroupAction(Request $request)
{
    $group = new Group();
    $form = $this->createForm(GroupType::class, $group);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($group);
        $em->flush();

        return View::create($group, 201);
    }

    return View::create($form, 400);
}

我发给的请求正文/api/groups

{
    "group": {
        "name": "Entwickler",
        "folder": [
            1
        ]
    }
}

我尝试了很多不同的方法来解决这个问题,但没有任何效果像我预期的那样。这让我抓狂了好几个小时。

感谢 Mathieu Dormeval,这就是解决方案。

我更改了组实体定义:

/**
 * @ORM\Entity(repositoryClass="App\Repository\GroupRepository")
 */
class Group

收件人:

/**
 * @ORM\Entity(repositoryClass="App\Repository\GroupRepository")
 * @ORM\Table(name="groups")
 */
class Group