原则2:批处理插入引用其他实体的实体时的怪异行为


Doctrine 2: weird behavior while batch processing inserts of entities that reference other entities

我正在尝试下面描述的批处理方法:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/batch-processing.html

我的代码是这样的

    $limit = 10000;
    $batchSize = 20;
    $role = $this->em->getRepository('userRole')->find(1);
    for($i = 0; $i <= $limit; $i++)
    {
        $user = new 'Entity'User;
        $user->setName('name'.$i);
        $user->setEmail('email'.$i.'@email.blah');
        $user->setPassword('pwd'.$i);
        $user->setRole($role);
        $this->em->persist($user);
         if (($i % $batchSize) == 0) {
             $this->em->flush();
             $this->em->clear();
        }
    }

的问题是,在第一次调用em->flush()之后$role被分离,并且对于每20个用户,一个具有新id的新角色已创建,这不是我想要的

对于这种情况是否有任何可用的解决方案?我唯一能做的就是每次在循环中获取用户角色实体

谢谢

clear()分离实体管理器管理的所有实体,因此$role也被分离,并且尝试持久保存一个分离的实体会创建一个新实体。

您应该在clear后再次获取角色:

$this->em->clear();
$role = $this->em->getRepository('userRole')->find(1);

或者直接创建一个引用:

$this->em->clear();
$role = $this->em->getReference('userRole', 1);

作为arnaud576875的答案的替代方案,您可以从实体管理器中分离 $user,以便可以立即进行GC处理。像这样:

$this->em->flush(); 
$this->em->detach($user); 
编辑:


正如Geoff指出的那样,这将只分离最新创建的用户对象。所以这个方法是不推荐