如何完全重置性能学说

How to fully reset doctrine for performance

我有一个带有 Doctrine 的 Symfony 应用程序。

我需要创建一个命令来遍历数据库中的数千条记录,检索相关数据并进行处理。

随着实体的加载,学说变得越来越慢 - 随着其身份映射的增加 - 从每秒处理数十条记录到每分钟仅处理几条记录。

我希望执行 $em->clear() 会重置原则并使我的流程更有效率,但在 clear() 之后处理更多结果时会生成以下异常。

[Doctrine\ORM\ORMInvalidArgumentException]
A new entity was found through the relationship 'App\Entity\XXXX' that was not configured to cascade persist operations for entity: XXXXXX.

To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"})

我的代码是这样的:

$qb = $repository->createQueryBuilder....;
$i = 0;
do {
    $list = $this->paginator->paginate($qb->getQuery(), $i, 10);
    foreach($list as $item){
        $this->processItem($item);
    }
    $this->em->clear();
    $i++;
} while(count($list) > 0);

如果我尝试在每次迭代中仅分离 $item,它会起作用,但在 processItem 期间加载的相关实体不会分离,因此 IdentityMap 不断增长。

这就像 clear() 并没有真正清除所有,或者在 clear() 之后并不是所有的实体都被正确地重新加载。

当然,如果我删除 clear() 函数,则不会触发错误。

在挖掘并检查了两次代码之后,感谢@NicolaiFröhlich,我找到了问题。

问题确实是在我的代码上部我加载了一些实体,然后在 clear() 从身份映射中删除之后,以及在 processItem 函数中使用的那些实体。