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;