2015-09-25 141 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 。 –