2015-09-25 87 views
0

我面临与自定义ID生成器,自动增量和Symfony(2.7)与Doctrine(2.5)和MySQL的教条迁移问题。Symfony2 Doctrine2自动增量字段与自定义ID生成器

当我使用自定义生成器时,id字段在migrations:diff输出中不会获得AUTO_INCREMENT状态。 当我在yaml中手动添加自动增量时,所有引用的表列也会获得AUTO_INCREMENT。

如何在不影响引用的情况下使用自定义生成器对我的主实体使用自动增量?

实体(sites.orm.yml):

type: entity 
table: sites 
id: 
    id: 
    type: integer 
    column: id 
    generator: 
     strategy: CUSTOM 
    customIdGenerator: 
     class: AssignableIdentityGenerator 

发电机:

class AssignableIdentityGenerator extends AbstractIdGenerator { 
    public function generate(EntityManager $em, $entity) { 
    return $entity->getId() ? : (int) $em->getConnection()->lastInsertId(); 
    } 

    public function isPostInsertGenerator() { 
    return true; 
    } 
} 

迁移:diff的输出保持被这(删除AUTO_INCREMENT):

ALTER TABLE sites CHANGE id id INT NOT NULL; 

如果我加

options: 
    autoincrement: true 

我没有得到一个ALTER的站点表,这是正确的,因为它使AUTO_INCREMENT,而是我得到

ALTER TABLE other_table CHANGE site_id site_id INT AUTO_INCREMENT NOT NULL; 

在引用表,这是不正确的。

主义本身suports的AUTO_INCREMENT与自己IdentityGenerator,我想我发现了主义现货\ ORM \工具\ SchemaTool :: gatherColumn其中该生效,但它在一个私有方法是深:

if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) { 
    $options['autoincrement'] = true; 
} 

不幸的是,Doctrine对扩展不是很友好(许多私有方法/属性或类被实例化,而不是使用注入服务)。

有没有人有解决这个问题的办法? 或者甚至可能是关于如何获得既可自动增量又可手动设置的ID字段的完全不同的想法。

回答

3

有没有人有解决这个问题的办法?或者,甚至可能是关于如何获得既可自动增量又可手动设置的ID字段的完全不同的想法。如果你想:

我对你这个解决方案:

第一:你需要设置你的ID策略,以 “AUTO”

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

二要手动设置您的ID,您需要更改班级的元数据(,然后刷新)。在那里,你可以改变你的IdGeneratorType

/** 
* @param EntityManager $em 
* @param mixed   $object 
*/ 
protected function changeIdGeneratorType(EntityManager $em, $object) 
{ 
    if ($object->getId() !== null) { 
     $metadata = $em->getClassMetadata(get_class($object)); 
     $metadata->setIdGeneratorType($metadata::GENERATOR_TYPE_NONE); 
    } 
} 

$metadata::GENERATOR_TYPE_NONE 

有了这个GeneratorType,你将能够手动设置你的ID。


现在,您将能够既自动递增的手动设定的ID

+0

感谢您的回复! 你能否澄清这个changeIdGeneratorType-Method在哪里? 我无法在任何地方找到它,并且它看起来不像您提到的“刷新之前”那样是一个有效的preFlush回调。 此外,它看起来像修改整个实体类的生成器。如果有另一个没有设置ID的实体,谁将其设置回AUTO? –

+0

'changeIdGeneratorType'可能是_AbstractIdGenerator_类的'generate(EntityManager $ em,$ entity)'函数。 – e1dar

+0

'changeIdGeneratorType'就是我自己的函数的名字。重要的部分是'if($ object-> getId()!== null){$ {$} = $ em-> getClassMetadata(get_class($ object)); $ metadata-> setIdGeneratorType($ metadata :: GENERATOR_TYPE_NONE); }你检查一个ID是否已经被设置,如果这是'** true **'你告诉你的对象将这个实例的生成器类型设置为'NONE',所以它会应用你之前设置的ID 。 –