使用“自动”策略时,显式设置标识与教条

我的实体使用这个注解为它的ID:

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

从一个干净的数据库,我从旧的数据库现有的logging导入,并试图保持相同的ID。 然后,当添加新logging时,我希望MySQL像往常一样自动增加ID列。

不幸的是,似乎Doctrine2完全忽略了指定的ID。


新解决scheme

根据以下build议,以下是首选解决scheme:

 $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()); 

旧解决scheme

由于Doctrineclosures了ClassMetaData以确定生成器策略,因此必须在pipe理EntityManager中的实体后对其进行修改:

 $this->em->persist($entity); $metadata = $this->em->getClassMetaData(get_class($entity)); $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); $this->em->flush(); 

我只是在MySQL上进行了testing,并且按照预期工作,这意味着具有自定义ID的实体与该ID一起存储,而没有指定ID的lastGeneratedId() + 1使用lastGeneratedId() + 1

虽然你的解决scheme在MySQL中工作的很好,但是我没有使它和PostgreSQL一起工作,因为它是基于序列的。

我要添加这条线,使其完美的工作:

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

最好的祝福,

也许什么学说改变了,但现在正确的方法是:

 $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); $metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); 

如果实体是类表inheritance的一部分,则需要更改两个实体(您所持有的实体和根实体)的类元数据中的ID生成器,

新的解决scheme只有在插入前所有实体都有id时才能正常工作 当一个实体有身份证,另一个实体没有 – 新的解决scheme失败。

我用这个函数导入我所有的数据:

 function createEntity(\Doctrine\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 \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata */ $generator = $metadata->idGenerator; $generatorType = $metadata->generatorType; $metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); $metadata->setIdGeneratorType(\Doctrine\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(); } } 

Doctrine 2.5和MySQL的解决scheme

“新解决scheme”不适用于Doctrine 2.5和MySQL。 你必须使用:

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

但是我只能确认对于MySQL,因为我还没有尝试过任何其他的DBMS。