首页 > 解决方案 > 表单 OneToMany 外键 null 违规

问题描述

当我提交表单和持久对象模型时出现SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "object_id"错误。

我有两个教义实体:

class Object {
    /**
     * @var Document[]|ArrayCollection
     * @ORM\OneToMany(targetEntity="App\Entity\Document", mappedBy="mainObject", cascade={"persist"})
     */
    private $documents;
}
class Document
{
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Object", inversedBy="documents")
     * @ORM\JoinColumn(nullable=false)
     */
    private $object;
}

和 Symfony 形式:

class ObjectType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('documents', CollectionType::class, [
                'allow_add' => true,
                'entry_type' => DocumentType::class,
            ])
        ;
    }
}

我的控制器代码:

$object = new Object();
$form = $this->formFactory->create(ObjectType::class, $object);
$form->submit(json_decode($request->getContent(), true), false);

if ($form->isSubmitted() && $form->isValid()) {
    $this->entityManager->persist($object);
    $this->entityManager->flush();
}

发生错误是因为 Doctrine 将 Document 保存在 Object 之前。是否可以更改保存行为?

标签: phpsymfonydoctrine

解决方案


要解决这个问题,您可以by_reference => false在集合类型上使用。通过将此设置为 false,您是在说始终使用方法而不是访问属性。

$builder
    ->add('documents', CollectionType::class, [
        'allow_add' => true,
        'entry_type' => DocumentType::class,
        'by_reference' => false,
    ]);

在某些情况下,将直接使用属性而不是方法。您可以在此处阅读有关此属性的更多信息。

在对象的方法上添加新文档时,您还需要设置addDocument()对象。这应该类似于:

public function addDocument(Document $document): object
{
    $document->setObject($this);

    $this->getDocuments()->add($document);

    return $this;
}

那应该可以解决您的问题。我也认为有一个实体命名object有点令人困惑。


推荐阅读