mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
OneToOne relationship with owning side having key of inverse side broken #5318
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 @asgrim on GitHub (Nov 9, 2016).
Originally assigned to: @lcobucci on GitHub.
gist created by @Ocramius shows a reproducible case for this issue: https://gist.github.com/Ocramius/7adc2079884991122ca95a74d2eb4927
When hydrating an entity constructed as per the gist above using
findOneBy, the ORM raises a notice startingNotice: Undefined index: targetToSourceKeyColumns. I believe the issue is not reproducible when usingfind.Unsure as to the root cause of the issue currently. Apologies for the vague description here, but @Ocramius will hopefully be able to provide more detail about this issue.
@lcobucci commented on GitHub (Nov 9, 2016):
I executed that gist (just changing the names to GH6124* to relate to this issue) and I had a different error on
master- so probably we already fixed that notice.Basically the ORM complains that it wasn't able to call the method
BasicEntityPersister#getCacheRegion()because the mapping side is not cacheable. However if I enable L2C on theOwingSideclass, and also on the association, the test passes withfind()andfindOneBy(): https://gist.github.com/lcobucci/665d1f03d72af1c03c5e76af6d64b1d1@asgrim commented on GitHub (Nov 9, 2016):
I think that may be related then; in this circumstance the owning side
GH6124OwningSidecan't be in the L2C as the contents are written to outside the scope of the application (not our choice, I hasten to add). Our workaround for now is to make it aOneToManyrelationship which works (although isn't ideal), as we can't rely on the contents being L2-cachable.@lcobucci commented on GitHub (Nov 9, 2016):
We need to think about what should be the behaviour of the L2C query regarding this... I mean, we could easily hack something on
DefaultQueryCache#putorDefaultQueryCache#storeAssociationCacheto bypass associations that are not L2-cacheable something like:But is this right?
@lcobucci commented on GitHub (Nov 10, 2016):
Maybe @guilhermeblanco can help us on this one
@lcobucci commented on GitHub (Jan 20, 2017):
Also mentioned on #5808 (but here we have more detail).
@lcobucci commented on GitHub (Feb 22, 2017):
@asgrim @Ocramius I was investigating this issue last evening and unfortunately my conclusion is that is not really worth to have a way to workaround the cache on this situation.
My suggestion is to simply make the schema validator add a warning. The reason for this is the way the ORM handles one-to-one associations.
What are your thoughts?
@Ocramius commented on GitHub (Feb 22, 2017):
A limitation warning referencing an issue is sufficient for me.
Marco Pivetta
http://twitter.com/Ocramius
http://ocramius.github.com/
On Wed, Feb 22, 2017 at 10:10 AM, Luís Cobucci notifications@github.com
wrote:
@guilhermeblanco commented on GitHub (Feb 22, 2017):
@lcobucci Did you re-run the test? It seems we already check for that in https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Cache/DefaultQueryCache.php#L249 and this shouldn't happen anymore.
However, it might be worth looking into switching the association to owning side and caching the owning side (which must be cacheable, or you would have an exception).
I'm long away of master (in develop there's no more
targetToSourceKeyColumns)... field is greener there! =)@lcobucci commented on GitHub (Feb 22, 2017):
@guilhermeblanco I did.
On master the problem is not the
targetToSourceKeyColumnsanymore but actually a call toBasicEntityPersister#getCacheRegion().I agree that we shouldn't allow that on
storeAssociationCache()and throw an exception but we should also alert the users that an uncached owning side on an one-to-one association is an invalid mapping.That's excellent!
@guilhermeblanco commented on GitHub (Feb 22, 2017):
@lcobucci Makes sense now... however I don't think it's a matter of implying to have a
@Cachemapped. *-to-one should be implicit per entity definition and added to the entity cache (not as a separate record). Let me try to explain:Whenever you have a class like this:
In this scenario, it is expected to have 2 cache entries:
As you may see, we don't necessarily need to add
@Cachein the *-to-one association since it must be implicit to exist in the owning side as part of the cache entry.If it doesn't, then you'd always be forced to query the DB even to build the proxy, defeating the purpose of having SLC at all. At the same time, if a *-to-many doesn't have
@Cacheconfigured, this means the second entry wouldn't exist, forcing the DB query to happen when loading the collection.There's also the limitation we introduced that other side must be cached (which means, both
GroupandPhonerequire to be@Cache).So here is where Doctrine becomes deficient: As you may see, this is not entirely required, but we enforce this because collection loading is fetched based on the owner id, which would completely trash the need of having the collection marked as
@Cache.We cannot safely rewrite the portions inside PersistentCollection to achieve that, so this requirement needs to stay until 3.0.
However, it's an optional action to cache the collection association (*-to-many), and implicit for *-to-one (owning side) associations.
Things get tricky when you have bi-directionals. I think it's worth discussing on this thread and properly implement. I don't think we should add a warning anywhere tbh.
@lcobucci commented on GitHub (Feb 22, 2017):
@guilhermeblanco it's not about
*-to-onebut ratherone-to-one. It happens because the ORM always tries to fetch the inversed side ofone-to-oneeagerly and that breaks stuff (if the entity is not cacheable on the L2C).So my suggestion to only force the
@Cacheon that situation.@lcobucci commented on GitHub (Jun 1, 2017):
@Ocramius @guilhermeblanco I was thinking about move this to
v3.0since we're changing a lot of things regarding mapping, do you agree?@Ocramius commented on GitHub (Jun 1, 2017):
Full ack - this can be fixed easily now that we have a stricter metadata API thanks to @guilhermeblanco's efforts.
@Webonaute commented on GitHub (Aug 11, 2017):
Is there a solutions for ppl who are waiting for this to be fixed? in the mean time of 3.0?
@Ocramius commented on GitHub (Aug 11, 2017):
@Webonaute if you didn't see one in the thread: no.
@asgrim commented on GitHub (Aug 14, 2017):
@Webonaute did you try:
@pkly commented on GitHub (Nov 23, 2023):
Hey, I just hit this issue when attempting to enable L2 cache for our application. Is there truly nothing else other than making it a OneToMany relationship? It breaks some assumptions in the db which is... not preferable, obviously.
I was hoping it'd be as simple as enabling cache on a couple of our entities but since the relationships are complex (about 190 entities) lack of support for this is a deal breaker, and L2 is essentially unusable.
Is there a reason it was moved away from a 3.0 release milestone? I'd love to see this resolved in the near future. Perhaps for now it'd be okay to simply mention that 1:1 relationships cannot be cached and instead either load them from database on request as usual or eagerly if set? It seems to me one could simply store some metadata instead which would tell it which cache key to read or if to pull it from db instead.
@vasilvestre commented on GitHub (Nov 19, 2025):
Any update about this ? It happens in Sylius