Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-549

\Doctrine\ORM\Mapping\DatabaseDriver::loadMetadataForClass fails to detect primary key when primary key is also a foreign key

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-BETA1
    • Fix Version/s: 2.0-BETA2
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      Encoutered this error while attempting to reverse engineer a database. Was previously working with 2.0-ALPHA4 so this is the result of some change between ALPHA4 and BETA1.

      The reverse engineering process fails with a Doctrine\ORM\Mapping\MappingException with message "No identifier/primary key specified for Entity `mytable`. Every entity must have an identifier/primary key."

      This exception is thrown because the "identifier" property of the ClassMetadataInfo object passed to loadMetadataForClass is not populated with the expected value (which in this case should be array('a_id', 'b_id')

      It appears that this is caused by the following code in \Doctrine\ORM\Mapping\DatabaseDriver::loadMetadataForClass():

                  // Skip columns that are foreign keys
                  foreach ($foreignKeys as $foreignKey) {
                      if (in_array(strtolower($column->getName()), array_map('strtolower', $foreignKey->getColumns()))) {
                          continue(2);
                      }
                  }
      

      The table definition is something like:

      CREATE TABLE a (
        a_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
        PRIMARY KEY (a_id)
      ) ENGINE=InnoDB;
      
      CREATE TABLE b (
        b_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
        PRIMARY KEY (b_id)
      ) ENGINE=InnoDB;
      
      /* this is the table that fails to be reverse engineered */
      CREATE TABLE mytable (
        a_id BIGINT UNSIGNED NOT NULL,
        b_id BIGINT UNSIGNED NOT NULL,
        PRIMARY KEY (a_id, b_id),
        CONSTRAINT `a_id_ibfk` FOREIGN KEY (`a_id`) REFERENCES `a` (`a_id`),
        CONSTRAINT `b_id_ibfk` FOREIGN KEY (`b_id`) REFERENCES `b` (`b_id`),
      ) ENGINE=InnoDB;
      

        Activity

        Hide
        Roman S. Borschel added a comment - - edited

        That table should probably be detected to be a many-many join table (no entity).

        Show
        Roman S. Borschel added a comment - - edited That table should probably be detected to be a many-many join table (no entity).
        Hide
        Jonathan H. Wage added a comment -

        I am not sure how we should fix this. Do you want to try and enhance the reverse engineering so it properly detects many2many reference tables? That seems like it might not work too well for most databases?

        Show
        Jonathan H. Wage added a comment - I am not sure how we should fix this. Do you want to try and enhance the reverse engineering so it properly detects many2many reference tables? That seems like it might not work too well for most databases?
        Hide
        Roman S. Borschel added a comment -

        @Jon: The report mentions this was working with ALPHA4 so I thought this is (was) already possible.

        @Marc: Can you maybe elaborate on how exactly ALPHA4 did behave? Did it detect the join table as an entity or as a many-many join table?

        Show
        Roman S. Borschel added a comment - @Jon: The report mentions this was working with ALPHA4 so I thought this is (was) already possible. @Marc: Can you maybe elaborate on how exactly ALPHA4 did behave? Did it detect the join table as an entity or as a many-many join table?
        Hide
        Marc Hodgins added a comment -

        @Roman Sorry, should have been more clear. It wasn't throwing an exception in ALPHA4 as far as I recall. It may not have actually been generating correct mappings.

        @Jon If reverse engineering the mapping is not possible, what about generating a class containing a comment to that effect? Or, skip the table with a warning and continue rather than throwing an exception. With an exception being thrown on the CLI, there is no way to work around it and reverse engineer the other tables.

        Show
        Marc Hodgins added a comment - @Roman Sorry, should have been more clear. It wasn't throwing an exception in ALPHA4 as far as I recall. It may not have actually been generating correct mappings. @Jon If reverse engineering the mapping is not possible, what about generating a class containing a comment to that effect? Or, skip the table with a warning and continue rather than throwing an exception. With an exception being thrown on the CLI, there is no way to work around it and reverse engineer the other tables.
        Hide
        Jonathan H. Wage added a comment -

        Ok, I suppose we need to work out something for the CLI that issues warning instead of fatal exceptions so that it can continue on building the other entities.

        Show
        Jonathan H. Wage added a comment - Ok, I suppose we need to work out something for the CLI that issues warning instead of fatal exceptions so that it can continue on building the other entities.

          People

          • Assignee:
            Jonathan H. Wage
            Reporter:
            Marc Hodgins
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: