Doctrine DBAL
  1. Doctrine DBAL
  2. DBAL-479

Doctrine2 schema-tool:update doesn't re-create foreign keys on entity change

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.5
    • Fix Version/s: 2.3
    • Component/s: None
    • Security Level: All
    • Labels:
      None

      Description

      I have changed a @ManyToOne relation to another entity. My workflow was this:

      • Having @ManyToOne(targetEntity="Entity\EntityA") in the source
      • Creating the database schema
      • Changing @ManyToOne(targetEntity="Entity\EntityA") to @ManyToOne(targetEntity="Entity\EntityB")
      • Calling doctrine orm:schema-tool:update

      orm:schema-tool:update doesn't notice that and doesn't re-create the FK on MySQL and PostgreSQL (haven't tested others).

        Issue Links

          Activity

          Hide
          Benjamin Eberlei added a comment -

          This was fixed in https://github.com/doctrine/dbal/commit/d7908fee and is part of Doctrine 2.3

          Show
          Benjamin Eberlei added a comment - This was fixed in https://github.com/doctrine/dbal/commit/d7908fee and is part of Doctrine 2.3
          Hide
          Joshua Smith added a comment -

          I've looked through the bugs in the DBAL project that reference the Comparator and I can't find one for this issue.

          Has one been created for it that I have missed?

          Also, I tried adding the suggested code into my project and schema-tool:update generated SQL to drop and recreate every foreign key relationship. I applied those changes and ran schema-tool:update again, expecting to get the normal "nothing to update" message. What I got was SQL to drop and recreate every foreign key relationship. Again.

          Tracing the code revealed that (in one case) $key1->getForeignTableName() was returning 'user' and $key2->getForeignTableName() was returning 'User'. All of the foreign key comparisons followed the same pattern. I applied strtolower() to each of them before the comparison and now things seem to behave as I expect, but I don't know how portable my solution is.

          if (strtolower($key1->getForeignTableName()) != strtolower($key2->getForeignTableName())) {
              return true;
          }
          

          I think applying strtolower() like this is OK since something similar is done when comparing local columns and foreign columns earlier in Comparator::diffForeignKey().

          Show
          Joshua Smith added a comment - I've looked through the bugs in the DBAL project that reference the Comparator and I can't find one for this issue. Has one been created for it that I have missed? Also, I tried adding the suggested code into my project and schema-tool:update generated SQL to drop and recreate every foreign key relationship. I applied those changes and ran schema-tool:update again, expecting to get the normal "nothing to update" message. What I got was SQL to drop and recreate every foreign key relationship. Again. Tracing the code revealed that (in one case) $key1->getForeignTableName() was returning 'user' and $key2->getForeignTableName() was returning 'User'. All of the foreign key comparisons followed the same pattern. I applied strtolower() to each of them before the comparison and now things seem to behave as I expect, but I don't know how portable my solution is. if (strtolower($key1->getForeignTableName()) != strtolower($key2->getForeignTableName())) { return true; } I think applying strtolower() like this is OK since something similar is done when comparing local columns and foreign columns earlier in Comparator::diffForeignKey().
          Hide
          Timo A. Hummel added a comment -

          I finally found the spot where the check is missing:

          Comparator::diffForeignKey misses to compare the foreign table name, which can be added as this:

          if ($key1->getForeignTableName() != $key2->getForeignTableName()) {
                 return true;
          }
          
          Show
          Timo A. Hummel added a comment - I finally found the spot where the check is missing: Comparator::diffForeignKey misses to compare the foreign table name, which can be added as this: if ($key1->getForeignTableName() != $key2->getForeignTableName()) { return true ; }
          Hide
          Timo A. Hummel added a comment -

          13:32:46 < beberlei> it is a DBAL issue, so you should start replicating it there
          13:33:10 < beberlei> i mean, have a look at how the DBAL SchemaDiff looks like in that case, and why it creates the sql wrong
          13:33:19 < beberlei> probably the comperator misses something

          Show
          Timo A. Hummel added a comment - 13:32:46 < beberlei> it is a DBAL issue, so you should start replicating it there 13:33:10 < beberlei> i mean, have a look at how the DBAL SchemaDiff looks like in that case, and why it creates the sql wrong 13:33:19 < beberlei> probably the comperator misses something
          Hide
          Timo A. Hummel added a comment -

          Any news of this issue?

          This is actually not a duplicate of DDC-1585.

          Show
          Timo A. Hummel added a comment - Any news of this issue? This is actually not a duplicate of DDC-1585 .
          Hide
          Timo A. Hummel added a comment -

          Yes, same variable name. For the real-world change, see:

          https://github.com/partkeepr/PartKeepr/commit/1cf520f6433dd4d14785a7791a6efe6ab67cc47c

          Show
          Timo A. Hummel added a comment - Yes, same variable name. For the real-world change, see: https://github.com/partkeepr/PartKeepr/commit/1cf520f6433dd4d14785a7791a6efe6ab67cc47c
          Hide
          Benjamin Eberlei added a comment -

          Does this use the same variable or does the many to one variable name change?

          Show
          Benjamin Eberlei added a comment - Does this use the same variable or does the many to one variable name change?

            People

            • Assignee:
              Benjamin Eberlei
              Reporter:
              Timo A. Hummel
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: