Doctrine批量插入 - 实体管理器清除

时间:2015-11-07 20:37:47

标签: php mysql symfony doctrine-orm

我想通过批处理将10 000行插入数据库。 在第一步中,我需要从数据库中选择一些对象,然后对这些对象进行交互,并为每个对象将另一个对象持久化到数据库。 这是代码示例:

 $em = $this->getDoctrine()->getManager();
    $products = $em->getRepository('MyBundle:Product')->findAll(); // return 10 000 products
    $category = $em->getRepository('MyBundle:Category')->find(1);
    $batchsize = 100;
    foreach ($products as $i => $product) {
        $entity = new TestEntity();
        $entity->setCategory($category);
        $entity->setProduct($product); // MyEntity And Product is OneToOne Mapping with foreign key in MyEntity
        $em->persist($entity);
        if ($i % $batchsize === 0) {
            $em->flush();
            $em->clear();
        }
    }
    $em->flush();
    $em->clear();

它返回此错误:

A new entity was found through the relationship 'Handel\GeneratorBundle\Entity\GenAdgroup#product' that was not configured to cascade persist operations for entity

我认为问题出在clear(),删除了内存中的所有对象,包括$ products和$ category

如果我使用cascade={"persist"}关联,则doctrine在db。中插入新的类别行。

经过一些尝试后,我犯了一些脏实体错误。

我做错了吗?这项工作的解决方案和最佳实践是什么? 非常感谢您的回答

2 个答案:

答案 0 :(得分:3)

解决方案只是清除那些正在改变/创建的对象。那些常量的应保留在EntityManager中。

喜欢这个

$em->clear(TestEntity::class);
$em->clear(...);

如果您在没有参数的情况下保持清除,它将分离实体管理器下当前的所有对象。这意味着如果您尝试重用它们,它会在您获得时抛出错误。例如,唯一的字段将被复制并抛出该错误。

答案 1 :(得分:0)

致电后

$em->clear();

类别对象变得无人值守。 您可以尝试在其上调用$ em-> merge($ category)方法。但可能最有保障的方法是再次获取它。

    if ($i % $batchsize === 0) {
        $em->flush();
        $em->clear();
        $category = $em->getRepository('MyBundle:Category')->find(1);
    }