Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-945

Crashing Bug: BasicEntityPersister::_getSelectColumnListSQL returns empty list, thus generating wrong SQL

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.0
    • Fix Version/s: 2.0.1, 2.1
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      I have a situation where Doctrine generates a wrong SQL query and crashes with an exception.

      The userland code calls the EntityManager::merge method.

      The query generated looks like "SELECT FROM SomeTable", meaning it has no select column list, and therefore it's plainly wrong.

      The entity I am trying to merge back into the entity manager is a regular entity with state detached. The class has a column which is declared as ID and filled with an autogenerated value, three regular columns, and a one-to-many relationship. The to-many-relationship causes BasicEntityPersister::loadOneToManyCollection() to be called, which in turn calls BasicEntityPersister::_getSelectEntitiesSQL, which then calls BasicEntityPersister::_getSelectColumnListSQL, which wrongly returns an empty string, thus leading to the corrupt query without a select column list being generated. The target entity of the one-to-many relationship is a mapped superclass, which has an ID (again with autogenerated values), and a many-to-one relationship inversing the one in the first entity. Further fields depend on its exact type as determined by the inheriting entities, but it will always have some.

      Here is the exception, up to the point where the trace leaves the ORM:

      exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM VersionedDataObject t0' at line 1' in /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/DBAL/Connection.php:577 Stack trace: #0 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/DBAL/Connection.php(577): PDO->query('SELECT FROM Ve...') #1 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/Persisters/BasicEntityPersister.php(1173): Doctrine\DBAL\Connection->executeQuery('SELECT FROM Ve...', Array) #2 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/UnitOfWork.php(1984): Doctrine\ORM\Persisters\BasicEntityPersister->loadOneToManyCollection(Array, Object(persistentData\model\versioning\InputComponentDataVersion), Object(Doctrine\ORM\PersistentCollection)) #3 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/PersistentCollection.php(207): Doctrine\ORM\UnitOfWork->loadCollection(Object(Doctrine\ORM\PersistentCollection)) #4 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/UnitOfWork.php(1441): Doctrine\ORM\PersistentCollection->initialize() #5 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/UnitOfWork.php(1323): Doctrine\ORM\UnitOfWork->doMerge(Object(persistentData\model\versioning\InputComponentDataVersion), Array) #6 /var/www/invoiceCreator/src/thirdPartyComponents/doctrine/Doctrine/ORM/EntityManager.php(520): Doctrine\ORM\UnitOfWork->merge(Object(persistentData\model\versioning\InputComponentDataVersion))

      This one is a blocker by user standards. The error means that it is impossible to use Doctrine in long-running batch jobs like in my situation, because it does not support merging certain detached objects back into the entity manager at all, while at some point they need to be detached for virtual memory capacity reasons.

        Activity

        Hide
        Daniel Alvarez Arribas added a comment -

        Added a more accurate description of both entities involved.

        Show
        Daniel Alvarez Arribas added a comment - Added a more accurate description of both entities involved.
        Hide
        Benjamin Eberlei added a comment -

        This is not enough information to reproduce this issue. We have tests that show merge and detach works. I need more code, mapping files and a reproduce set.

        If yo udont want to attach it to the issue you can send me a mail.

        Show
        Benjamin Eberlei added a comment - This is not enough information to reproduce this issue. We have tests that show merge and detach works. I need more code, mapping files and a reproduce set. If yo udont want to attach it to the issue you can send me a mail.
        Hide
        Daniel Alvarez Arribas added a comment -

        After analyzing the problem further, I think it is nothing but a subsequent error due to the bidirectional association in the mapped superclass, which is documented to not work in the first place, as relationships declared in mapped superclasses must be unidirectional. After changing the mapped superclass to a regular entity, the application is working.

        The only remaining problem in this case is the crashing effect. This is due to the rudimentary data model validation combined with the total lack of decent error messages in Doctrine 2. As there is no apparent relationship between the symptom (exception due to incorrect SQL being generated) and the effective technical source of the problem (bidirectional relationship declared in a mapped superclass), it is unnecessarily cumbersome to determine what possible sources of error to look for. It would be great if doctrine could defend itself against non-conforming data model inputs by producing an understandable error message instead of just crashing.

        I will leave this bug open as a validation issue.

        Show
        Daniel Alvarez Arribas added a comment - After analyzing the problem further, I think it is nothing but a subsequent error due to the bidirectional association in the mapped superclass, which is documented to not work in the first place, as relationships declared in mapped superclasses must be unidirectional. After changing the mapped superclass to a regular entity, the application is working. The only remaining problem in this case is the crashing effect. This is due to the rudimentary data model validation combined with the total lack of decent error messages in Doctrine 2. As there is no apparent relationship between the symptom (exception due to incorrect SQL being generated) and the effective technical source of the problem (bidirectional relationship declared in a mapped superclass), it is unnecessarily cumbersome to determine what possible sources of error to look for. It would be great if doctrine could defend itself against non-conforming data model inputs by producing an understandable error message instead of just crashing. I will leave this bug open as a validation issue.
        Hide
        Benjamin Eberlei added a comment -

        Yeah this is annoying, i check if we can implement a cheap runtime validation when loading the class metadata.

        Show
        Benjamin Eberlei added a comment - Yeah this is annoying, i check if we can implement a cheap runtime validation when loading the class metadata.
        Hide
        Benjamin Eberlei added a comment -

        Throwing mapping exception if using a mapped superclass with ManyToMany or OneToMany association now.

        Show
        Benjamin Eberlei added a comment - Throwing mapping exception if using a mapped superclass with ManyToMany or OneToMany association now.
        Hide
        Daniel Alvarez Arribas added a comment -

        Thanks for fixing this.

        Shouldn't it actually only throw an exception when using bidirectional associations with a mapped superclass?

        Show
        Daniel Alvarez Arribas added a comment - Thanks for fixing this. Shouldn't it actually only throw an exception when using bidirectional associations with a mapped superclass?
        Hide
        Benjamin Eberlei added a comment -

        Not exactly but you are right, unidirectional Many To Many associations work if you use the Mapped Superclass only once. I will adjust the patch accordingly.

        For 2.1 there will be an additional feature described in DDC-964 that allows overriding certain mapped superclass details to avoid these problems.

        Show
        Benjamin Eberlei added a comment - Not exactly but you are right, unidirectional Many To Many associations work if you use the Mapped Superclass only once. I will adjust the patch accordingly. For 2.1 there will be an additional feature described in DDC-964 that allows overriding certain mapped superclass details to avoid these problems.
        Hide
        Benjamin Eberlei added a comment -

        Corrected.

        Show
        Benjamin Eberlei added a comment - Corrected.
        Hide
        Benjamin Eberlei added a comment -

        A related Github Pull-Request [GH-218] was
        https://github.com/doctrine/doctrine2/pull/218

        Show
        Benjamin Eberlei added a comment - A related Github Pull-Request [GH-218] was https://github.com/doctrine/doctrine2/pull/218
        Hide
        Benjamin Eberlei added a comment -

        A related Github Pull-Request [GH-335] was opened
        https://github.com/doctrine/doctrine2/pull/335

        Show
        Benjamin Eberlei added a comment - A related Github Pull-Request [GH-335] was opened https://github.com/doctrine/doctrine2/pull/335

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Daniel Alvarez Arribas
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: