Acabo de buscar una entidad (fila) de la base de datos:

$one = $em->getRepository()->find(1);

E intentando insertar otra entidad que tiene una clave externa con $one:

for($i=0; $i<=100; $i++) {
   $two = new TwoEntity();
   $two->setOne($one); // as you can see $one is just a foreign key. Referenced.
   $two->setSomething(true);
   $em->persist($two);

   ...
   // when each 20th cycle flush them. and clear.
   $em->flush();
   $em->clear();
}

Nota : utilizo la forma de inserción por lotes de Doctrine2. Simplemente minimicé el código para una explicación más corta de lo que estoy tratando de hacer.

En lugar de hacer referencia a $one, Doctrine intenta volver a insertar $one. Da la excepción de persistencia y si persisto $one, solo intenta insertar $one una y otra vez. Error: A new entity was found through the relationship...

¿Cómo puedo hacer referencia a $one e insertar solo $two en lote?

Actualización : probé también el método $one->addTwo($two) en $one pero esta vez los errores desaparecieron, pero los campos de clave externa están vacíos.

Actualización 2:

Hice Side Owning y Side Inverse para poner todo en cascada . De esta manera, si fusiono $em->merge($one), simplemente funciona. Pero no sé si esta es la forma correcta.

0
xangr 15 dic. 2016 a las 01:54

2 respuestas

La mejor respuesta

Haces $em->clear(); por lo que $one ya no se hace referencia en Doctrine.

Docblock de método claro dice:

Clears the ObjectManager. All objects that are currently managed by this ObjectManager become detached.

Simplemente elimine $em->clear(); o use algo como esto $em->clear('TwoEntity');

1
Pierre 15 dic. 2016 a las 00:08

Esto es incorrecto:

$two->setOne($one); // as you can see $one is just a foreign key. Referenced.

Lo que debes hacer es algo como esto:

$two->setOne( $one->getId() );

O algo así. En otras palabras, obtenga la identificación de referencia. En este momento, está configurando un objeto, no un identificador. A menos que realmente desee agregar el objeto a la nueva Entidad $ dos, lo que haría de manera diferente. Háganos saber si ese es el caso.

0
Alvin Bunk 14 dic. 2016 a las 23:45