简体   繁体   English

Symfony / Doctrine在内存中未更新

[英]Symfony/Doctrine not updating in memory

I suspect this is a straightforward problem about entities not updating in memory. 我怀疑这是关于实体不在内存中更新的直接问题。

Here are my repository functions: 这是我的存储库功能:

public function insertTask($information)
{
        ...

        $entityManager = $this->getEntityManager();
        $entityManager->persist($taskObj);
        $entityManager->flush();

        // Update the task defects for this task
        $this->updateTaskDefectTaskIds($taskObj->getId(), $task['defects']);

        return $taskObj;
}


private function updateTaskDefectTaskIds($task, $defects)
{
        $taskDefectIds = array();

        foreach ($defects as $defect)
        {
            $taskDefectIds[] = intval($defect['taskDefectId']);
        }

        // Update the task IDs on the task defects
        $this->getEntityManager()
            ->createQuery('UPDATE Model:TaskDefect td SET td.task = :task WHERE td.id IN (:taskDefectIds)')
            ->setParameter('task', $task)
            ->setParameter('taskDefectIds', $taskDefectIds)
            ->execute();

        $this->getEntityManager()->flush();
}

This appears to be working. 这似乎正在工作。 Basically I have: - Task table - TaskDefect table 基本上我有:-任务表-TaskDefect表

TaskDefects by virtue of the way the app is written, get inserted before the Task does. TaskDefects通过编写应用程序的方式而在Task之前插入。 But this means I need to, once the Task is eventually added, update the TaskDefect records to point to the new TaskId. 但这意味着,一旦最终添加了Task,我就需要更新TaskDefect记录以指向新的TaskId。

The problem I face though, is somewhere in memory (from the actual database side of things it is updating correctly) it's not picking up my changes. 但是,我面临的问题是内存中的某个位置(从实际数据库的角度来看,它正在正确更新),它没有接受我的更改。 For example, I update some TaskDefects to point to the new TaskId - but then I access the Task object and it says there are no defects. 例如,我更新了一些TaskDefects以指向新的TaskId-但随后我访问Task对象,并说没有缺陷。

If I go to another page, and try and access the same task - then it says there are defects. 如果我转到另一个页面,然后尝试访问同一任务-则表明存在缺陷。

So I feel I'm missing a flush() or a persist() or something which is stopping the entities in memory from updating. 所以我觉得我缺少flush()persist()或其他东西阻止了内存中的实体进行更新。 Obviously reloading a page forces the refresh and it works fine then. 显然,重新加载页面会强制刷新,然后可以正常工作。

Here's what I have in my controller: 这是我的控制器中的内容:

$task = $repository->insertTask($content); // i figured maybe at this point it's too much to expect the task obj to magically update

$updatedTask = $repository->findOneById($task->getId()); // so I grab it again... but no luck

var_dump($updatedTask->getDefects()); // ... because this returns no defects

Any ideas welcome. 任何想法欢迎。 Thanks. 谢谢。

This line in insertTask: insertTask中的这一行:

return $taskObj;

Has no connection to what is happening in updateTaskDefectTaskIds because you're not modifying $taskObj at all, you're just passing an id value, then updating defect objects via DQL. 与updateTaskDefectTaskIds中发生的事情没有任何关系,因为您根本不需要修改$ taskObj,您只是传递一个id值,然后通过DQL更新缺陷对象。

If you'd like $taskObj to reflect your defect additions from insertTask you would do something like this: 如果您希望$ taskObj反映出insertTask中的缺陷添加,您将执行以下操作:

public function insertTask($information)
{
    ...

    $entityManager = $this->getEntityManager();
    $entityManager->persist($taskObj);
    $entityManager->flush();

    // Update the task defects for this task
    $this->updateTaskDefectTaskIds($taskObj, $task['defects']);

    return $taskObj;
}


private function updateTaskDefectTaskIds($taskObj, $defects)
{
    foreach ($defects as $defect)
    {
        $defect = $this->getEntityManager()->getRepository('YourBundle:Defect')->find(intval($defect['taskDefectId']));

        if ($defect instanceof Defect) {

            $defect->setTaskObj($taskObj);
            $this->getEntityManager()->persist($defect);
            $taskObj->addDefect($defect);
        }
    }

    $this->getEntityManager()->persist($taskObj);
    $this->getEntityManager()->flush();
}

Or, if you don't mind an extra db call just refresh $taskObj in insertTask like this: 或者,如果您不介意额外的数据库调用,只需在insertTask中刷新$ taskObj,如下所示:

$this->getEntityManager()->refresh($taskObj);
return $taskObj;

Also, doctrine loves to cache what you have in memory, so if it doesn't have any reason to check the db (in your code example it can't know about your change) then it will just happily serve you up the stale object when you fetch the entity by id. 另外,主义喜欢缓存您的内存,因此,如果它没有任何理由检查数据库(在您的代码示例中,它不知道您的更改),那么它将很乐意为您提供过时的对象当您通过ID获取实体时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM