【问题标题】:Doctrine2: Adding existing entity to parent, duplicates the parentDoctrine2:将现有实体添加到父级,复制父级
【发布时间】:2015-08-07 05:32:19
【问题描述】:

我有两个相关的类(OneToMany):

<?php
class Container {
    /**
     * @var Content[]
     * @\Doctrine\ORM\Mapping\OneToMany(targetEntity="Content", mappedBy="contents", cascade={"remove"})
     */
    protected $contents;
}

class Content {
    /**
     * @var Container
     * @\Doctrine\ORM\Mapping\ManyToOne(targetEntity="Container", inversedBy="contents", cascade={"persist"})
     */
    public $container;
}

现在,当我添加一个新的内容项时,容器将在数据库中复制,并且新的内容项链接到副本。

我使用父Container的id,像这样:

<?php
$newContent->container = $repository->find($passedIdOfContainer);

// ...

$em->persist($newContent);
$em->flush();

所以基本上我只是从数据库中获取现有实体记录(有效),并使用现有对象设置我的新内容对象的属性。但是现在父级(容器)将被复制。

当我删除 cascade={"persist"} 时,我收到以下错误:

通过关系“Content#Container”找到了一个新实体 未配置为对实体进行级联持久化操作: 容器@0000...

我需要做什么,以创建新的孩子,参考父母,而不在数据库中复制父母?

【问题讨论】:

    标签: php doctrine-orm cascade


    【解决方案1】:
    use Doctrine\ORM\Mapping as ORM;
    
    class Container
    {
        /**
         * @var object
         *
         * @ORM\OneToMany(
         *      targetEntity="Content",
         *      mappedBy="container",
         *      cascade={"persist", "remove"}
         * )
         */
        protected $contents;
    }
    
    use Doctrine\ORM\Mapping as ORM;
    
    class Content
    {
        /**
         * @var object
         *
         * @ORM\ManyToOne(
         *      targetEntity="Container",
         *      inversedBy="contents"
         * )
         * @ORM\JoinColumn(
         *      name="container_id",
         *      referencedColumnName="id",
         *      onDelete="CASCADE",
         *      nullable=false
         * )
         */
        protected $container;
    }
    

    假设您在 Container 实体文件中设置了所有方法,那么:

    //......
    $container->addContents($contentObject);
    
    $em->persist($container);
    $em->flush();
    

    【讨论】:

    • 我不能在内容中设置父容器而不是将内容添加到父容器吗?
    • 当有这种简单而通用的方式来处理您想要实现的目标时,您为什么需要这样的事情?您的业​​务案例是什么?
    • 按照您的建议,我已尝试更改保持关系的方式。现在至少,父级没有重复。 JoinColumn 似乎没有效果。 DB结构相同。但是当我持久化容器时,“container_id”列是 NULL。当我设置 nullable=false 时,我得到一个 sql 错误,NULL 是不允许的。我用$container-&gt;addContent($content); 添加了内容,在这个方法中我调用$this-&gt;contents-&gt;add($content)。 $this->contents 在构造函数中填充了new \Doctrine\Common\Collections\ArrayCollection()。为什么 container_id 保持为空?
    • 我认为您有不同的问题,所以如果不动手,我真的无法提供帮助。您可能会重构代码。
    • 将内容添加到容器中会在内容表中创建一条新记录。只是关系没有持久化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多