DDC-945: Crashing Bug: BasicEntityPersister::_getSelectColumnListSQL returns empty list, thus generating wrong SQL #5475

Closed
doctrinebot opened this Issue Dec 22, 2010 · 11 comments

2 participants

@doctrinebot

Jira issue originally created by user dalvarez:

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.

@doctrinebot

Comment created by dalvarez:

Added a more accurate description of both entities involved.

@doctrinebot

Comment created by @beberlei:

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.

@doctrinebot

Comment created by dalvarez:

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.

@doctrinebot

Comment created by @beberlei:

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

@doctrinebot

Comment created by @beberlei:

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

@doctrinebot

Issue was closed with resolution "Fixed"

@doctrinebot

Comment created by dalvarez:

Thanks for fixing this.

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

@doctrinebot

Comment created by @beberlei:

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.

@doctrinebot

Comment created by @beberlei:

Corrected.

@doctrinebot

Comment created by @beberlei:

A related Github Pull-Request [GH-218] was
#218

@doctrinebot

Comment created by @beberlei:

A related Github Pull-Request [GH-335] was opened
#335

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added this to the 2.0.1 milestone Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment