EntityManager: очищать только объекты определенного типа

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);
}

}

Поскольку я хочу очистить сообщения, но хочу сохранить типы сущностей Автор и Категория, я ожидал, что $entityName = 'Acme\BlogBundle\Entity\Post', $entityName = get_class($post); или же $entityName = Acme\BlogBundle\Entity\Post::class поможет, но, к сожалению, ничего не понятно.

Как правильно использовать этот параметр?

3

Решение

Вы можете передать имя класса как entityName в метод очистки entitymanager, но оно должно быть точно таким же, как единица работы доктрины, хранящаяся в его карте идентификации. Чтобы получить правильный, вы должны сделать что-то вроде этого:

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]