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 à partir d'une ancienne base de données et j'essaie de conserver les mêmes IDs. 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
Conformément aux recommandations ci-dessous, voici 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
Parce que Doctrine se base sur les ClassMetaData pour déterminer la stratégie de génération, il doit être modifié après la gestion de l'entité dans l'EntityManager :
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$this->em->flush();
J'ai simplement testé ceci sur MySQL et cela a fonctionné comme prévu, cela signifie que les entités avec un ID personnalisé ont été stockées avec cet ID, tandis que celles sans ID spécifié utilisaient le lastGeneratedId() + 1
.
0 votes
Utilisez-vous doctrine pour importer les enregistrements existants?
0 votes
Non, malheureusement les données sont extraites via une API externe au format JSON, puis mappées aux classes d'entité.
0 votes
Eric, cela ne fonctionne-t-il pas avec @GeneratedValue(strategy="NONE")?
2 votes
Eric, peu importe ... Je vois ce que vous essayez de faire. Vous avez essentiellement besoin d'un @GeneratedValue(strategy="ItDepends") :)
1 votes
Une chose à noter à propos de cela, c'est qu'il semble que les générateurs de Id qui ne sont pas "isPostInsertGenerator" == true, auront déjà été exécutés. Vous pouvez changer la valeur de l'ID après la persistance, cependant, vous perdrez un numéro de séquence.
16 votes
La nouvelle solution ne me permet plus de définir l'identifiant dans une fixture doctrine. Cependant, en utilisant $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); permet d'initialiser l'identifiant et de le sauvegarder. (MySQL).
0 votes
La nouvelle solution n'a pas fonctionné pour moi avec MySQL. J'ai dû la faire fonctionner avec votre ancienne solution ci-dessus. Merci.
0 votes
@jmoz Merci, ça a fonctionné pour moi!
0 votes
Si vous écrivez explicitement le nom de la classe d'entité, n'incluez pas de barre oblique initiale. Histoire d'horreur complète ici: stackoverflow.com/questions/24454899/…
0 votes
La nouvelle solution ne fonctionne pas en 2.3
0 votes
Veuillez noter que l'
id
de l'entité ne peut pas être défini manuellement sur0
. Vous devez utiliser un nombre plus grand. Lorsque 0 est spécifié, le générateur utilisera toujours la stratégie AUTO. Testé avec doctrine 2.42 votes
La nouvelle solution ne fonctionne pas dans Symfony 3.0. J'ai dû utiliser
$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
0 votes
@piotrekkr merci pour le conseil, ça a également fonctionné pour moi sur Symfony 3.3
0 votes
Pour que cela fonctionne, j'ai dû mettre à jour le générateur avant d'appeler $this->em->persist()