mirror of
https://github.com/doctrine/orm.git
synced 2026-03-23 22:42:18 +01:00
Collection is empty for one-to-many association using class table inheritance #6989
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @NordFox7 on GitHub (Jun 7, 2022).
Bug Report
Summary
The
Collectionof aOne-To-Many Associationis empty when using a junction entity havingClass Table Inheritanceto connect 2 entities.I have 2 entities (
Field&Mapping) which I want to "connect" using junction entities which inherit of aAssignmententity which uses a composite key to connect them both.Something like this:
I'm using a junction entity because I want to store additional data in the assignment/connection.
Also, I want to retrieve all the mappings a field is assigned/connected to, and also in the other direction retrieve all the fields a mapping has connected/assigned.
Therefore, I use a
One-To-Many Associationinside theField&Mappingentity which should return a list ofAssignment*entities but when calling, theCollectionis empty.I checked all association's and the stored database rows, also the fetching query, and executed them manually and all are correct.
How to reproduce
My investigation and possible bug discovery/solution
I tried to investigate the problem myself and I noticed the query is correct, and the row data is received in the
ObjectHydratorbut the identifier is not detected, and the row is therefore discarded.I noticed in
ObjectHydrator.php:467that the row got discared because the$nonemptyComponentswas empty.I also noticed when the
Assignmentis a single entity (without inheritance) everything works as expected and$nonemptyComponentswas not empty and also theCollectionhad all entities correctly.Therefore, I checked how the
$nonemptyComponentsgets filled, which happens inAbstractHydrator.php:477if the identifier for the row data is found and is notnull. For the single entity that worked, but not for my inheritedAssignment*entity.Therefore, I checked how the identifier is detected and this happens in the select column query-building part where the column is checked if it is an id, which is different for single and inherited entities.
The single entity will use the
BasicEntityPersisterand at line1348if the column is an id, theResultSetMappingwill get informed by that, which will result in the$nonemptyComponentsnot being empty, and therefore theCollectionnot empty.The inherited entity will use the
JoinedSubclassPersisterwhich inherits theAbstractEntityInheritancePersisterclass and at line77the column will be selected but theisIdentifierparameter which informs theResultSetMappingfor an found id column is hardcoded tofalse, which will result in an always empty$nonemptyComponentsand therefore an always emptyCollection.I found that very strange, why is that hardcoded to
false?I confirmed that by adding the same id detection code for the
JoinedSubclassPersisteras it is in theBaseEntityPersisterand theCollectionwas indeed correctly filled with desired entities.But this is no permanent solution because I modified the vendor files.
I almost wanted to do an pull request with this fix, but because I don't fully understand the inner workings of doctrine, I was not sure if that is correct what I did. Because there must be a reason it is hardcoded to
falseright? Maybe the id column is detected somewhere else for joined rows?@oojacoboo commented on GitHub (Oct 27, 2022):
Having a very similar issue with a
OneToManyrelationship where thetargetEntityis using inheritance mapping. The Collection is just empty. When looking at the query logs, I don't actually see any attempts to even query the database. It's as if Doctrine considers the Collection to be initialized already. Thefetchmode has no bearing on it and I tried even specifying one of the sub entities in the discriminator map as thetargetentity for the relationship. That doesn't work either.@FoxLess can you share your modification code for this?
@NordFox7 commented on GitHub (Oct 28, 2022):
I actually made a bugfix which I wanted to publish as a pull request... but as I stated in my post I was not sure if my change is correct... Also it would probably take a while until it is merged into the main branch and I needed a faster fix. (Also it seemed that nobody else had any issue with it)
For my case, I just changed my code from a Composite identifier to a Single identifier by changing the code from:
to this:
Which may or may not an ideal case for you. @oojacoboo
The underlaying issue is that doctrine does not detect a composite key as an identifier and does not load the collection then.
I may actually do that pull request in case somebody else is stumbling on that issue.
@oojacoboo commented on GitHub (Oct 28, 2022):
I see @FoxLess. So, it looks like your issue is related to composite identifiers. In our case, it's strictly related to class table inheritance.
@NordFox7 commented on GitHub (Oct 28, 2022):
Well yes, my issue occurs with class table inheritance using composite identifiers because they are not detected in this combination.
I made a pull request, but it seems to have breaking changes, so don't expect it to be in doctrine for a while. But you can check the code for the changes I made, in case you use a fork of doctrine. @oojacoboo
@oojacoboo commented on GitHub (Oct 29, 2022):
@FoxLess thanks. I was actually able to test this. It doesn't resolve the issue I'm having. But thanks for sharing. Your PR seems reasonable to me and hopefully it can be included in the next larger release.
@TracKer commented on GitHub (Mar 29, 2023):
@oojacoboo Did you find any working solution for the issue?
@oojacoboo commented on GitHub (Mar 29, 2023):
@TracKer I don't even recall. We don't currently have an outstanding issue, so we either resolved it or found a work-around. Not sure if you're using any SQL filters with your entities, but Doctrine does a terrible job with them in respect to relational entities and query caching. You're going to need to log the actual SQL statements issued from Doctrine to really get to the bottom of things. We just enable query logging at the rdbms level to see what SQL statements Doctrine is cooking up.