Mi entidad usa esta anotación para su ID:
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
De una base de datos limpia, estoy importando registros existentes de una base de datos más antigua y trato de mantener las mismas ID. Luego, al agregar nuevos registros, quiero que MySQL aumente automáticamente la columna de ID como de costumbre.
Desafortunadamente, parece que Doctrine2 ignora por completo el ID especificado.
Nueva solucion
Según las recomendaciones a continuación, la siguiente es la solución preferida:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Solución antigua
Debido a que Doctrine gira fuera de ClassMetaData para determinar la estrategia del generador, debe modificarse después de administrar la entidad en EntityManager:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$this->em->flush();
Acabo de probar esto en MySQL y funcionó como se esperaba, lo que significa que las Entidades con una ID personalizada se almacenaron con esa ID, mientras que aquellas sin una ID especificada usaron el lastGeneratedId() + 1
.
fuente
$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
Respuestas:
Aunque su solución funciona bien con MySQL, no logré que funcione con PostgreSQL ya que se basa en secuencias.
Tengo que agregar esta línea para que funcione perfectamente:
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Atentamente,
fuente
$em->persist($entity)
.Quizás lo que cambió la doctrina pero ahora de la manera correcta es:
fuente
ClassMetadata
es una interfaz y por lo tanto no puede tener constantes.$metadata::GENERATOR_TYPE_NONE
En caso de que la entidad sea parte de la herencia de una tabla de clases , debe cambiar el generador de id en los metadatos de la clase para ambas entidades (la entidad que persiste y la entidad raíz)
fuente
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
errores. Voto en contraLa nueva solución funciona bien solo cuando TODAS las entidades tienen una identificación antes de la inserción. Cuando una entidad tiene ID y otra no, la nueva solución está fallando.
Utilizo esta función para importar todos mis datos:
fuente
Solución para Doctrine 2.5 y MySQL
La "Nueva solución" no funciona con Doctrine 2.5 y MySQL. Tienes que usar:
Sin embargo, solo puedo confirmar eso para MySQL, porque todavía no he probado ningún otro DBMS.
fuente
He creado una biblioteca para establecer identificaciones futuras para las entidades de Doctrine. Vuelve a la estrategia de generación de ID original cuando se consumen todas las ID en cola para minimizar el impacto. Debería ser fácil para las pruebas unitarias para que un código como este no tenga que repetirse.
fuente
Inspirándome en el trabajo de Villermen , creé la biblioteca tseho / doctrine-assign-identity que te permite asignar identificaciones manualmente a una entidad de Doctrine, incluso cuando la entidad usa las estrategias AUTO, SEQUENCE, IDENTITY o UUID.
Nunca debe usarlo en producción, pero es realmente útil para pruebas funcionales.
La biblioteca detectará automáticamente las entidades con una identificación asignada y reemplazará el generador solo cuando sea necesario. La biblioteca recurrirá al generador inicial cuando una instancia no tenga una identificación asignada.
El reemplazo del generador ocurre en un EventListener de Doctrine, sin necesidad de agregar ningún código adicional en sus dispositivos.
fuente