【问题标题】:When is Doctrine 2 making errors with composite keys?Doctrine 2 何时使用复合键出错?
【发布时间】:2023-03-07 16:59:05
【问题描述】:

我最近正在阅读Doctrine 2's best practices 并被此阻止:

25.3。避免使用复合键
即使 Doctrine 完全支持复合键,如果可能最好不要使用它们。复合键 需要 Doctrine 的额外工作,因此有更高的概率 错误。

我不明白的是:如果"Doctrine fully supports composite keys",在处理这样的键时怎么会出错?

因此,我想以社区 wiki 的身份提出这个问题,希望它能帮助我们了解 "probability of errors" 是什么:

您是否有示例可以分享您遇到的Doctrine 2 未能很好地处理复合键/应有的情况?

【问题讨论】:

    标签: doctrine doctrine-orm composite-key


    【解决方案1】:

    就我而言,我相信我已经遇到了一个非常基本的数据库架构的问题,该架构包含一个主键由 2 个外键组成的表:

    当我生成模型时,没有创建与product_i18n 实体对应的实体

    $ php doctrine-module.php orm:convert-mapping --namespace="Dbi\Entity\\" \
    --from-database --force annotation module/Dbi/src/
    Processing entity "Dbi\Entity\Locale"
    Processing entity "Dbi\Entity\Product"
    
    $ php doctrine-module.php orm:generate-entities --generate-annotations=1 \
    module/Dbi/src
    Processing entity "Dbi\Entity\Locale"
    Processing entity "Dbi\Entity\Product"
    

    然而,我相信我的database schema 是正确创建的:

      PRIMARY KEY (`product_id`, `locale_id`) ,
      INDEX `fk_product_i18n_locale` (`locale_id` ASC) ,
      INDEX `fk_product_i18n_product` (`product_id` ASC) ,
      CONSTRAINT `fk_product_i18n_locale`
        FOREIGN KEY (`locale_id` )
        REFERENCES `mydb`.`locale` (`id` ),
      CONSTRAINT `fk_product_i18n_product`
        FOREIGN KEY (`product_id` )
        REFERENCES `mydb`.`product` (`id` )
    

    另外,Doctrine 2Schema Manager 表明 Doctrine 似乎完全理解这种关系(var_dump 输出已更改以使其更简洁:删除诸如 arrayRECURSIONstring 之类的内容。 ..):

    $em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
    $sm = $em->getConnection()->getSchemaManager();
    var_dump($sm->->listTables());
    
    object(Doctrine\DBAL\Schema\Table)#290 (10) {
    ["_name":protected]=> "product_i18n"
    
    ["_indexes":protected]=>
      ["primary"]=>
        ["_columns":protected]=>
          [0]=> "product_id"
          [1]=> "locale_id"
    
    ["_fkConstraints":protected]=>
      ["fk_product_i18n_locale"]=>
      object(Doctrine\DBAL\Schema\ForeignKeyConstraint)#285 (9) {
        ["_localColumnNames":protected]=> "locale_id"
        ["_foreignTableName":protected]=> "locale"
        ["_foreignColumnNames":protected]=> "id"
    
      ["fk_product_i18n_product"]=>
      object(Doctrine\DBAL\Schema\ForeignKeyConstraint)#286 (9) {
        ["_localColumnNames":protected]=> "product_id"
        ["_foreignTableName":protected]=> "product"
        ["_foreignColumnNames":protected]=> "id"
    

    因此,我可以查询 product_i18n 表的架构,但由于未生成相应的实体模型,因此无法与该表交互。

    更新:正如user1136666 指出的那样:known issues and limitations page 颂歌声明如下:

    虽然我们声明我们支持复合主键,但不支持 目前包括外键作为主键列。

    解决方法是定义代理键并在外键上添加唯一约束,如下所示:

    CREATE  TABLE IF NOT EXISTS `mydb`.`product_i18n` (
      `id` INT NOT NULL AUTO_INCREMENT ,
      `name` VARCHAR(45) NULL ,
      `description` TEXT NULL ,
      `created_at` DATETIME NULL ,
      `modified_at` DATETIME NULL ,
      `product_id` INT NOT NULL ,
      `locale_id` INT NOT NULL ,
      INDEX `fk_product_i18n_locale` (`locale_id` ASC) ,
      INDEX `fk_product_i18n_product` (`product_id` ASC) ,
      PRIMARY KEY (`id`) ,
      UNIQUE (`locale_id` , `product_id`),
      CONSTRAINT `fk_product_i18n_locale`
        FOREIGN KEY (`locale_id` )
        REFERENCES `mydb`.`locale` (`id` )
      CONSTRAINT `fk_product_i18n_product`
        FOREIGN KEY (`product_id` )
        REFERENCES `mydb`.`product` (`id` )
    ENGINE = InnoDB;
    

    功能请求:http://www.doctrine-project.org/jira/browse/DDC-1926

    【讨论】:

      【解决方案2】:

      表 product_i18n 的问题是它没有主键。请尝试将product_idlocale_id 设置为复合主键。 Doctrine 2 将生成实体。原则 2 实体需要主键。

      【讨论】:

      • 不,它没有:PRIMARY KEY (`product_id`, `locale_id`)?
      • 对不起,我没有看到他们。我认为真正的问题是使用主键作为外键。我尝试过不将它们用作外键,它们可以工作!请在此处查看docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/… 此案例仍在 Doctrine 2 限制中。
      • 确实创建了一个代理键作为主键来代替由外键组成的主键解决了这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 2014-01-18
      相关资源
      最近更新 更多