Doctrine2: Impossible to override the generated value strategy?

I have an object with an identifier as such:

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

I am transferring data to this object and want to keep existing keys. I looked at Id explicitly set Id using Doctrine when using the "AUTO" strategy , and found that I should be able to do the following:

 $newData = ... // array containing data to bring in $newEntity = new MyEntity(); $newEntity->setId($newData['id']); $newEntity->... // set other data fields $em->persist($newEntity); $metadata = $em->getClassMetadata('\CS\AcmeBundle\Entity\MyEntity'); $metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); $em->flush(); 

However, Doctrine does not use the provided ID. He ignores it when pasting. I also tried this approach, as some people seem to be lucky with it (even tried both):

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

But it does not change anything. The identifier is still automatically added to the database. In the query log, I see that Doctrine is not even trying to insert an identifier.

If I remove @ORM\GeneratedValue(strategy="AUTO") from MyEntity annotations, then the migration will match the provided ID that I give it. But I want to redefine it only during migration.

I am using Doctrine 2.4.2.

+2
symfony doctrine doctrine2
Jun 27 '14 at 2:56
source share
2 answers

For this method to work, you must use the second of them:

 $metadata = $em->getClassMetadata('\CS\AcmeBundle\Entity\MyEntity'); $metadata = $em->getClassMetadata('CS\AcmeBundle\Entity\MyEntity'); 

The problem is that Doctrine will return the same class metadata values ​​for both. They both correctly identify the class file, read its annotations, etc. Obviously, they are equivalent, except that this is an absolute namespace and the other is not.

But these strings will return different instances from getClassMetadata . Changes in one will not be reflected in the other. If you want your intended method to work, you should use the second form, because this is what UnitOfWork uses. He uses this normalization:

 // \Doctrine\ORM\UnitOfWork->getCommitOrder() ... $className = $this->em->getClassMetadata(get_class($entity))->name; $class = $this->em->getClassMetadata($className); ... 

Note that in a related question, the solution uses get_class($entity) . This is probably enough to get the right behavior.




In even more detail: after repeatedly entering the code, I noticed that \Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory memoizing both versions of the class name string in its private property $loadedMetadata . The version that was used to actually erase the objects was the one that does not have a leading slash, and I edited it with a slash.

Since both rows return the same data, I think this is an implementation error.

+1
Jul 21 '14 at 3:37
source share

Differences between GeneratedValue Strategies

Inside your organization

Replace

 @ORM\GeneratedValue(strategy="AUTO") 

from

 @ORM\GeneratedValue(strategy="NONE") 

I am not sure if you use annotations or xml or yml files. Therefore, it is better to modify the xml or yml entity files in your package configuration.

0
Feb 17 '15 at 6:15
source share



All Articles