Définir explicitement Id avec Docsortingne lors de l’utilisation de la stratégie «AUTO»

Mon entité utilise cette annotation pour son identifiant:

/** * @orm:Id * @orm:Column(type="integer") * @orm:GeneratedValue(strategy="AUTO") */ protected $id; 

A partir d’une firebase database propre, j’importe des enregistrements existants à partir d’une ancienne firebase database et tente de conserver les mêmes identifiants. Ensuite, lors de l’ajout de nouveaux enregistrements, je souhaite que MySQL incrémente automatiquement la colonne ID, comme d’habitude.

Malheureusement, Docsortingne2 ignore complètement l’ID spécifié.


Nouvelle solution

Selon les recommandations ci-dessous, la solution préférée est la suivante:

 $this->em->persist($entity); $metadata = $this->em->getClassMetaData(get_class($entity)); $metadata->setIdGeneratorType(\Docsortingne\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); $metadata->setIdGenerator(new \Docsortingne\ORM\Id\AssignedGenerator()); 

Ancienne solution

Étant donné que Docsortingne pivote 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(\Docsortingne\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); $this->em->flush(); 

Je viens de tester cela sur MySQL et cela fonctionnait comme prévu, ce qui signifie que les entités avec un identifiant personnalisé étaient stockées avec cet ID, tandis que celles sans identifiant spécifié utilisaient lastGeneratedId() + 1 .

    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 la séquence.

    Je dois append cette ligne pour que cela fonctionne parfaitement:

    $metadata->setIdGenerator(new \Docsortingne\ORM\Id\AssignedGenerator());

    Meilleures salutations,

    Peut-être que cette docsortingne a changé, mais maintenant la bonne façon est:

     $metadata->setIdGeneratorType(\Docsortingne\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); 

    Dans le cas où l’entité fait partie d’un inheritance de table de classe, vous devez changer le générateur d’identifiant dans les métadonnées de classe des deux entités (l’entité que vous persistez et l’entité racine).

    La nouvelle solution ne fonctionne bien que lorsque toutes les entités ont un identifiant avant insertion. Lorsqu’une entité a un identifiant et qu’une autre ne le fait pas, une nouvelle solution échoue.

    J’utilise cette fonction pour importer toutes mes données:

     function createEntity(\Docsortingne\ORM\EntityManager $em, $entity, $id = null) { $className = get_class($entity); if ($id) { $idRef = new \ReflectionProperty($className, "id"); $idRef->setAccessible(true); $idRef->setValue($entity, $id); $metadata = $em->getClassMetadata($className); /** @var \Docsortingne\ORM\Mapping\ClassMetadataInfo $metadata */ $generator = $metadata->idGenerator; $generatorType = $metadata->generatorType; $metadata->setIdGenerator(new \Docsortingne\ORM\Id\AssignedGenerator()); $metadata->setIdGeneratorType(\Docsortingne\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); $unitOfWork = $em->getUnitOfWork(); $persistersRef = new \ReflectionProperty($unitOfWork, "persisters"); $persistersRef->setAccessible(true); $persisters = $persistersRef->getValue($unitOfWork); unset($persisters[$className]); $persistersRef->setValue($unitOfWork, $persisters); $em->persist($entity); $em->flush(); $idRef->setAccessible(false); $metadata->setIdGenerator($generator); $metadata->setIdGeneratorType($generatorType); $persisters = $persistersRef->getValue($unitOfWork); unset($persisters[$className]); $persistersRef->setValue($unitOfWork, $persisters); $persistersRef->setAccessible(false); } else { $em->persist($entity); $em->flush(); } } 

    Solution pour Docsortingne 2.5 et MySQL

    La “nouvelle solution” ne fonctionne pas avec Docsortingne 2.5 et MySQL. Vous devez utiliser:

     $metadata = $this->getEntityManager()->getClassMetaData(Entity::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_‌​NONE); 

    Cependant, je ne peux que le confirmer pour MySQL, car je n’ai pas encore essayé de SGBD.

    J’ai créé une bibliothèque pour définir les futurs identifiants des entités Docsortingne. Il rétablit la stratégie de génération d’ID d’origine lorsque tous les ID en queue sont utilisés pour minimiser l’impact. Ce devrait être un simple repository pour les tests unitaires afin que ce type de code ne doive pas être répété.

    Inspiré par le travail de Villermen , j’ai créé cette bibliothèque qui vous permet d’affecter manuellement des identifiants à une entité Docsortingne, même lorsque l’entité utilise les stratégies AUTO, SEQUENCE, IDENTITY ou UUID.

    Vous ne devriez pas l’utiliser dans la production.

    La bibliothèque détecte automatiquement les entités avec un identifiant atsortingbué et ne remplace le générateur que lorsque cela est nécessaire. La bibliothèque se replie sur le générateur initial lorsqu’une instance n’a pas d’identifiant.

    Le remplacement du générateur se produit dans un Docsortingne EventListener, inutile d’append du code supplémentaire dans vos appareils.