Mon entité utilise cette annotation pour son ID:
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
À partir d'une base de données propre, j'importe des enregistrements existants d'une base de données plus ancienne et j'essaie de conserver les mêmes identifiants. Ensuite, lors de l'ajout de nouveaux enregistrements, je veux que MySQL incrémente automatiquement la colonne ID comme d'habitude.
Malheureusement, il semble que Doctrine2 ignore complètement l'ID spécifié.
Nouvelle solution
Selon les recommandations ci-dessous, ce qui suit est la solution préférée:
$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());
Ancienne solution
Étant donné que Doctrine pivote hors de ClassMetaData pour déterminer la stratégie du générateur, elle doit être modifiée après avoir géré l'entité dans EntityManager:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$this->em->flush();
Je viens de tester cela sur MySQL et cela a fonctionné comme prévu, ce qui signifie que les entités avec un ID personnalisé étaient stockées avec cet ID, tandis que celles sans ID spécifié utilisaient le lastGeneratedId() + 1
.
$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
Réponses:
Bien que votre solution fonctionne correctement avec MySQL, je n'ai pas réussi à la faire fonctionner avec PostgreSQL car elle est basée sur une séquence.
Je dois ajouter cette ligne pour que cela fonctionne parfaitement:
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Meilleures salutations,
la source
$em->persist($entity)
.Peut-être ce que la doctrine a changé, mais maintenant la bonne manière est:
la source
ClassMetadata
s'agit d'une interface et ne peut donc pas avoir de constantes.$metadata::GENERATOR_TYPE_NONE
Dans le cas où l'entité fait partie d'un héritage de table de classe, vous devez changer le générateur d'id dans les métadonnées de classe pour les deux entités (l'entité que vous persistez et l'entité racine)
la source
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
erreurs. DownvoteLa nouvelle solution ne fonctionne correctement que lorsque TOUTES les entités ont un identifiant avant l'insertion. Lorsqu'une entité a un ID et une autre pas, la nouvelle solution échoue.
J'utilise cette fonction pour importer toutes mes données:
la source
Solution pour Doctrine 2.5 et MySQL
La "Nouvelle solution" ne fonctionne pas avec Doctrine 2.5 et MySQL. Vous devez utiliser:
Cependant, je ne peux que le confirmer pour MySQL, car je n'ai encore essayé aucun autre SGBD.
la source
J'ai créé une bibliothèque pour définir les futurs ID des entités Doctrine. Il revient à la stratégie de génération d'ID d'origine lorsque tous les ID en file d'attente sont consommés pour minimiser l'impact. Cela devrait être une entrée facile pour les tests unitaires afin que du code comme celui-ci n'ait pas à être répété.
la source
Inspiré par le travail de Villermen , j'ai créé la bibliothèque tseho / doctrine-assigned-identity qui vous permet d'attribuer manuellement des ID à une entité Doctrine, même lorsque l'entité utilise les stratégies AUTO, SEQUENCE, IDENTITY ou UUID.
Vous ne devriez jamais l'utiliser en production mais c'est vraiment utile pour les tests fonctionnels.
La bibliothèque détectera automatiquement les entités avec un identifiant attribué et ne remplacera le générateur qu'en cas de besoin. La bibliothèque se replie sur le générateur initial lorsqu'une instance n'a pas d'identifiant attribué.
Le remplacement du générateur se produit dans un Doctrine EventListener, pas besoin d'ajouter de code supplémentaire dans vos appareils.
la source