tl;dr:如何使用Doctrine\ORM\EntityManager::clear()使用$entityName
假设我有一个Post实体,它有一个Author和一个Category。我想把帖子添加到我的数据库(随机的,从csv文件或其他)。添加数据时出现性能问题。内存使用量增加了,进程也变慢了,但我不知道如何(部分)清除entitymanager。
这是魔法发生的循环:

$batchSize = 250;
foreach ($posts as $post) {
    //$post['author'] is instance of Acme\BlogBundle\Author
    $post = new Post($post['author'], $post['category']);
    $em->persist($post);

    if ($i % $batchSize == 0) {
        $entity = '??';
        $em->flush();
        $em->clear($entityName);

        gc_collect_cycles();
    }
}

这将抛出Doctrine\ORM\ORMInvalidArgumentException: A new entity was found through the relationship Acme\BlogBundle\Post#author。这是正确的,因为Author由已清除的entitymanager管理。
这是明确的方法:
namespace Doctrine\ORM;
class EntityManager implements EntityManagerInterface {
 /**
 * Clears the EntityManager. All entities that are currently managed
 * by this EntityManager become detached.
 *
 * @param string|null $entityName if given, only entities of this type will get detached
 *
 * @return void
 */
public function clear($entityName = null)
{
    $this->unitOfWork->clear($entityName);
}

}

因为我想清除这些帖子,但是想保留author和category实体类型,所以我希望$entityName = 'Acme\BlogBundle\Entity\Post'$entityName = get_class($post);$entityName = Acme\BlogBundle\Entity\Post::class会有帮助,但不幸的是它没有清除任何内容。
如何正确使用此参数?

最佳答案

您可以将类名作为entityname传递给entitymanager clear方法,但它必须与条令工作单元在其标识映射中存储的完全相同。为了得到正确的答案,你应该这样做:

$classMetadata = $em->getClassMetadata(get_class($post));
$entityName = $classMetadata->rootEntityName;

07-24 12:35