[DDC-945] Crashing Bug: BasicEntityPersister::_getSelectColumnListSQL returns empty list, thus generating wrong SQL Created: 22/Dec/10  Updated: 14/Apr/12  Resolved: 28/Dec/10

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: ORM
Affects Version/s: 2.0
Fix Version/s: 2.0.1, 2.1
Security Level: All

Type: Bug Priority: Minor
Reporter: Daniel Alvarez Arribas Assignee: Benjamin Eberlei
Resolution: Fixed Votes: 0
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.



 Comments   
Comment by Daniel Alvarez Arribas [ 22/Dec/10 ]

Added a more accurate description of both entities involved.

Comment by Benjamin Eberlei [ 22/Dec/10 ]

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.

Comment by Daniel Alvarez Arribas [ 25/Dec/10 ]

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.

Comment by Benjamin Eberlei [ 27/Dec/10 ]

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

Comment by Benjamin Eberlei [ 28/Dec/10 ]

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

Comment by Daniel Alvarez Arribas [ 29/Dec/10 ]

Thanks for fixing this.

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

Comment by Benjamin Eberlei [ 31/Dec/10 ]

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.

Comment by Benjamin Eberlei [ 31/Dec/10 ]

Corrected.

Comment by Benjamin Eberlei [ 22/Mar/12 ]

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

Comment by Benjamin Eberlei [ 14/Apr/12 ]

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

Generated at Thu Oct 23 07:06:36 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.