无法在 API POST 调用中包含实体集合
Unable to include Collection of Entities inside API POST-call
问题中的错误:
Entity of type App\Entity\Nutt is missing an assigned ID for field 'squirrel'.
The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called.
If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
我完全可以调用 api POST 将 Squirrel 实体添加到数据库中。
使用此 Squirrel 的 ID,我可以执行 POST 对 Nutt 实体的调用,结果是 Nutt 表中的正确相关记录。
我似乎无法工作的是允许 Squirrel api 调用包含我想在同一个 api 调用中插入的相关 Nutts 集合。
我做错了什么?
JSON调用:
{
"name": "Jake",
"nutts": [
{
"size": 10,
"color": "blue"
}
]
}
松鼠实体
/**
* @ORM\Entity
* @ORM\Table(name="squirrel")
*/
class Squirrel {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=100)
* @Assert\NotBlank()
*
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Nutt", mappedBy="squirrel", cascade={"persist", "remove"})
*/
private $nutts;
public function __construct()
{
$this->nutts = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getNutts(): ?Collection
{
return $this->nutts;
}
public function setNutts(Collection $nutts)
{
foreach ($nutts as $nutt)
{
$this->nutts->add($nutt);
}
}
public function addNutt(Nutt $nutt): Squirrel
{
$this->nutts->add($nutt);
return $this;
}
}
松鼠实体已更新。
setNutts 已更改为:
public function setNutts(Collection $nutts)
{
foreach ($nutts as $nutt)
{
$nutt->setSquirrel($this);
$this->nutts->add($nutt);
}
}
实体纳特
/**
* @ORM\Entity
* @ORM\Table(name="nutt")
*/
class Nutt {
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Squirrel", inversedBy="nutts")
* @ORM\Id
*/
private $squirrel;
/**
* @ORM\Column(type="integer")
* @ORM\Id
*/
private $size;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $color;
/**
* @return Squirrel|null
*/
public function getSquirrel(): ?Squirrel
{
return $this->squirrel;
}
/**
* @param Squirrel|null $squirrel
* @return $this
*/
public function setSquirrel(?Squirrel $squirrel): self
{
$this->squirrel = $squirrel;
return $this;
}
//getters and setters for the rest
}
实体 Nutt 已更新。
属性 $squirrel 删除了它的 id 符号,因为它是一个关系:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Squirrel", inversedBy="nutts")
*/
private $squirrel;
松鼠控制器
/**
* Squirrel controller.
* @Route("/api", name="api_")
*/
class SquirrelController extends AbstractFOSRestController
{
/**
* Lists all Squirrels.
* @Rest\Get("/squirrels")
* @return Response
*/
public function getSquirrelAction()
{
$repository = $this->getDoctrine()->getRepository(Squirrel::class);
$squirrels = $repository->findall();
return $this->handleView($this->view($squirrels));
}
/**
* Create Squirrel.
* @Rest\Post("/squirrel")
*
* @return Response
*/
public function postSquirrelAction(Request $request)
{
$squirrel = new Squirrel();
$form = $this->createForm(SquirrelType::class, $squirrel);
$data = json_decode($request->getContent(), true);
$form->submit($data);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($squirrel);
$em->flush();
return $this->handleView($this->view(['status' => 'ok'], Response::HTTP_CREATED));
}
return $this->handleView($this->view($form->getErrors()));
}
}
以及我目前的关注点
松鼠形态
class SquirrelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add(
'nutts',
CollectionType::class, [
'entry_type' => NuttType::class,
'allow_add' => true,
'by_reference' => false
])
->add('save', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Squirrel::class,
'csrf_protection' => false
));
}
}
有一个 nutt 形式,但它工作正常。
@mel 在评论中解决了问题
Id
annotation 将该列声明为主键,因此它成为强制性的。但在这种情况下不需要,因为 squirrel
是一个关系。
错误本身也提示保存实体时该字段为空,因此未调用 setSquirrel
。
您也可以从 size
中删除注释。
问题中的错误:
Entity of type App\Entity\Nutt is missing an assigned ID for field 'squirrel'.
The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called.
If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.
我完全可以调用 api POST 将 Squirrel 实体添加到数据库中。 使用此 Squirrel 的 ID,我可以执行 POST 对 Nutt 实体的调用,结果是 Nutt 表中的正确相关记录。
我似乎无法工作的是允许 Squirrel api 调用包含我想在同一个 api 调用中插入的相关 Nutts 集合。
我做错了什么?
JSON调用:
{
"name": "Jake",
"nutts": [
{
"size": 10,
"color": "blue"
}
]
}
松鼠实体
/**
* @ORM\Entity
* @ORM\Table(name="squirrel")
*/
class Squirrel {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=100)
* @Assert\NotBlank()
*
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Nutt", mappedBy="squirrel", cascade={"persist", "remove"})
*/
private $nutts;
public function __construct()
{
$this->nutts = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getNutts(): ?Collection
{
return $this->nutts;
}
public function setNutts(Collection $nutts)
{
foreach ($nutts as $nutt)
{
$this->nutts->add($nutt);
}
}
public function addNutt(Nutt $nutt): Squirrel
{
$this->nutts->add($nutt);
return $this;
}
}
松鼠实体已更新。
setNutts 已更改为:
public function setNutts(Collection $nutts)
{
foreach ($nutts as $nutt)
{
$nutt->setSquirrel($this);
$this->nutts->add($nutt);
}
}
实体纳特
/**
* @ORM\Entity
* @ORM\Table(name="nutt")
*/
class Nutt {
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Squirrel", inversedBy="nutts")
* @ORM\Id
*/
private $squirrel;
/**
* @ORM\Column(type="integer")
* @ORM\Id
*/
private $size;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
private $color;
/**
* @return Squirrel|null
*/
public function getSquirrel(): ?Squirrel
{
return $this->squirrel;
}
/**
* @param Squirrel|null $squirrel
* @return $this
*/
public function setSquirrel(?Squirrel $squirrel): self
{
$this->squirrel = $squirrel;
return $this;
}
//getters and setters for the rest
}
实体 Nutt 已更新。 属性 $squirrel 删除了它的 id 符号,因为它是一个关系:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Squirrel", inversedBy="nutts")
*/
private $squirrel;
松鼠控制器
/**
* Squirrel controller.
* @Route("/api", name="api_")
*/
class SquirrelController extends AbstractFOSRestController
{
/**
* Lists all Squirrels.
* @Rest\Get("/squirrels")
* @return Response
*/
public function getSquirrelAction()
{
$repository = $this->getDoctrine()->getRepository(Squirrel::class);
$squirrels = $repository->findall();
return $this->handleView($this->view($squirrels));
}
/**
* Create Squirrel.
* @Rest\Post("/squirrel")
*
* @return Response
*/
public function postSquirrelAction(Request $request)
{
$squirrel = new Squirrel();
$form = $this->createForm(SquirrelType::class, $squirrel);
$data = json_decode($request->getContent(), true);
$form->submit($data);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($squirrel);
$em->flush();
return $this->handleView($this->view(['status' => 'ok'], Response::HTTP_CREATED));
}
return $this->handleView($this->view($form->getErrors()));
}
}
以及我目前的关注点 松鼠形态
class SquirrelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add(
'nutts',
CollectionType::class, [
'entry_type' => NuttType::class,
'allow_add' => true,
'by_reference' => false
])
->add('save', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Squirrel::class,
'csrf_protection' => false
));
}
}
有一个 nutt 形式,但它工作正常。
@mel 在评论中解决了问题
Id
annotation 将该列声明为主键,因此它成为强制性的。但在这种情况下不需要,因为 squirrel
是一个关系。
错误本身也提示保存实体时该字段为空,因此未调用 setSquirrel
。
您也可以从 size
中删除注释。