OneToMany关系不会与新实体一起持续存在

Gor*_*ika 3 symfony doctrine-orm

当我尝试使用symfony表单持久保存实体集合时,我遇到了一些问题.我按照官方文档,但由于此错误,我无法使其工作:

Entity of type ProductItem has identity through a
foreign entity Product, however this entity has no identity itself. You have to call    
EntityManager#persist() on the related  entity and make sure that an identifier was 
generated before trying to persist ProductItem. In case of Post Insert ID 
Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you 
have to call EntityManager#flush() between both persist operations.
Run Code Online (Sandbox Code Playgroud)

我必须与OneToMany关系链接的实体:

产品

/**
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
protected $id;

/**
 * @ORM\OneToMany(targetEntity="ProductItem", mappedBy="product",cascade={"persist"})
 */
protected $items;
Run Code Online (Sandbox Code Playgroud)

和ProductItem

/**
 * @ORM\Id()
 * @ORM\ManyToOne(targetEntity="Product", inversedBy="items")
 */
protected $product;

/**
 * @ORM\Id()
 * @ORM\ManyToOne(targetEntity="Item")
 */
protected $item;
Run Code Online (Sandbox Code Playgroud)

这是它添加到表单的方式:

->add('items','collection',array(
            'label' => false,
            'type' => new ProductItemType(),
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false))
Run Code Online (Sandbox Code Playgroud)

这是控制器动作:

public function newAction()
{
    $product= new Product();

    $form = $this->createForm(new ProductType(), $product);
    if($request->isMethod("POST"))
    {
        $form->handleRequest($request);
        if($form->isValid())
        {
            $em = $this->getDoctrine()->getManager();
            $em->persist($product);
            $em->flush();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在控制器中肯定做错了,因为正如错误消息所说,我必须在添加$ productItems之前保留$ product,但是我该怎么办呢?

我只是在尝试持久化新实体时遇到此错误,如果实体之前已经存在,我可以添加为可能的项目,因为我想成功

Kon*_*ski 6

我上周遇到了完全相同的问题,这是我在一些阅读和测试后找到的解决方案.

问题是您的产品实体具有级联持久性(通常是好的)并且它首先尝试持久化ProductItemProductItem实体不能持久化,因为它们需要首先持久化产品及其ID(复合键(产品,项目)).

有两种方法可以解决这个问题:

第一个我没有使用它,但你可以简单地删除一个复合键并使用带有外键的标准idProduct

第二 - 更好这可能看起来像黑客,但相信我这是你现在能做的最好的.它不需要对DB结构进行任何更改,并且可以使用表单集合而不会出现任何问题.

我的代码中的代码片段,文章部分有复合键(article_id,random_hash).临时设置一对多引用一个空数组,持久化,添加原始数据并再次持久(和刷新).

    if ($form->isValid())
    {
        $manager = $this->getDoctrine()->getManager();

        $articleSections = $article->getArticleSections();
        $article->setArticleSections(array());  // this won't trigger cascade persist
        $manager->persist($article);
        $manager->flush();

        $article->setArticleSections($articleSections);
        $manager->persist($article);
        $manager->flush();
Run Code Online (Sandbox Code Playgroud)