2011-09-15 7 views
6

Estoy probando el método de procesamiento por lotes se describe aquí: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/batch-processing.htmlDoctrina 2: Comportamiento extraño, mientras que las inserciones de procesamiento por lotes de las entidades que hacen referencia a otras entidades

mi código es el siguiente

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

el problema es , que después de la primera llamada a em-> flush() también se separa el rol $ y para cada 20 usuarios se crea un nuevo rol con un nuevo ID , que no es lo que quiero

¿hay alguna solución disponible para esta situación? único que podría hacer el trabajo es ir a buscar la entidad rol de usuario cada vez que en el bucle

gracias

Respuesta

14

clear() separa todas las entidades gestionadas por el gestor de la entidad, por lo $role se separa también, y tratar de persistir una entidad separada crea una nueva entidad

Usted debe buscar el papel de nuevo después de claro:

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

O simplemente crear una referencia en su lugar:

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

Como alternativa a arnaud576875 de que respuesta podría separar los $ usuario de la administrador de la entidad para que pueda recibir GC de inmediato. De este modo:

$this->em->flush(); 
$this->em->detach($user); 

Editar:
Como señala Geoff esto solamente separar la última creado por el usuario a objetos. Por lo tanto, este método es no se recomienda.

+1

Eso solo separaría al último usuario, no a los 19 que lo siguieron, corrígeme si me equivoco. –

+0

@Geoff maldición, creo que tienes razón. Editaré mi respuesta. –

0

Otra alternativa es merge el papel de vuelta después de la clara:

if (($i % $batchSize) == 0) { 
    $this->em->flush(); 
    $this->em->clear(); 
    $this->em->merge($role); 
} 

No estoy seguro de lo caro merge() es - si tuviera que adivinar, diría ir con la sugerencia de Arnaud de usando getReference()

+0

gracias, voy a probar este también – bazo

Cuestiones relacionadas