教义:通过关系发现了一个新实体...尝试刷新时

Posted

技术标签:

【中文标题】教义:通过关系发现了一个新实体...尝试刷新时【英文标题】:Doctrine: A new entity was found through the relationship... when trying to flush 【发布时间】:2015-10-26 14:35:32 【问题描述】:

一段时间以来,我一直在尝试解决这个问题,但失败了:当我尝试在 Doctrine 2.3 中保留一个新实体并在之后刷新时,我收到:

CRITICAL: Doctrine\ORM\ORMInvalidArgumentException: A new entity was 通过不存在的关系“Task#parentTask”找到 配置为实体级联持久化操作

我有一个自引用实体 Task,它看起来 - 在精简视图中 - 像这样:

class Task

    /**
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
     private $id;

     /** 
     * @ManyToOne(targetEntity="tasks\classes\Task", inversedBy="childTasks", fetch="LAZY")
     * @JoinColumn(name="parent", referencedColumnName="id")
     */
    private $parentTask;

    /** 
     * @OneToMany(targetEntity="tasks\classes\Task", mappedBy="parentTask", fetch="LAZY")
     */
    private $childTasks;

基于这项任务,我 现在我正在使用 QueryBuilder 中内置的查询来获取任务:

   function getTasksCreatedByUser($user) 
   
        $em = $this->db->getEntityManager();
        $qb = $em->createQueryBuilder();
        $query = $qb->select("t")
            ->from("tasks\classes\Task", "t")
            ->where($qb->expr()->andX(
                "t.creator = :creator"
                // plus more conditions here
            ))  
            ->setParameter("creator", $user)
            ->orderBy("t.id", "DESC")
            ->getQuery()
            ;   
        return $query->getResult();
       

对于这些任务中的每一个,我都创建了一个新任务,将它们引用为 $parentTask(代码缩短):

foreach($tasks as $task) 
    $newTask = new \tasks\classes\Task();
    $newTask->setParentTask($task);
    $db->persist($newTask);

class DB

    public function persist($entity)
    
        $this->entityManager->persist($object);
        $this->entityManager->flush();

    

在我的应用程序的其他部分,相同的模式可以正常工作,但我找不到有什么区别。

谁能帮我理解为什么抛出异常?我通读了十几个引用相同异常的其他线程,通常情况是两个对象之间存在某种关系,到目前为止都没有持久存在;一个会被持久化,另一个不会,这会抛出异常。不过,我看不到这种情况发生。

感谢任何帮助!

【问题讨论】:

【参考方案1】:

在你的 Task 类中试试这个注解。

/** 
 * @OneToMany(targetEntity="tasks\classes\Task", mappedBy="parentTask", cascade="persist", "remove", fetch="LAZY")
 */
private $childTasks;

【讨论】:

还是一样 :-(。我尝试为 $parentTasks 添加相同的内容,它只是在数据库中创建(子和父)任务的新副本。【参考方案2】:

我找到了解决问题的方法。我会在这里解释一下,希望有一天能对其他人有所帮助。

我的应用程序有两部分:一部分是我的 Web 界面的 REST 后端;另一部分是我的 Web 界面的 REST 后端;第二部分提供 CLI 操作以执行更长的计算。对于两者,我使用相同的代码实例化一个 Doctrine EntityManager。我将此 EntityManager#1 用于访问数据库的多个模型和帮助程序类。

但是,由于我忘记了我已经有一个实例的事实,我在我的 CLI 代码 (EntityManager#2) 中创建了第二个 entityManager,用于处理特定于 CLI 的数据库访问。这导致了这种情况:getTasksCreatedByUser() 与 EntityManager#1 一起使用,但 foreach($tasks as $task) 中的部分与 EntityManager#2 一起使用。

当我取消第二个实例化时,一切都像魅力一样工作。

【讨论】:

以上是关于教义:通过关系发现了一个新实体...尝试刷新时的主要内容,如果未能解决你的问题,请参考以下文章

教义存储库与私人成员

两个实体之间的教义关系

教义关系是否会影响应用程序性能?

教义多对多关系问题

教义自定义存储库方法和非托管实体

Symfony:通过控制器更新外键的教义