New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partial objects get cached and break "actual" objects #7633
Comments
This issue still open? We have the same problem over here. Is there a fix already or some workaround? |
Still not fixed as far as I know, and no response here either :/
The workaround is to never cache queries that resolve partial objects. If you actually need to cache partial object results for whatever reason, don't use Doctrine Cache for it, cache it yourself.
…________________________________
From: Fabian Köstring <notifications@github.com>
Sent: Thursday, September 5, 2019 14:51
To: doctrine/orm
Cc: Jiří Barouš; Author
Subject: Re: [doctrine/orm] Partial objects get cached and break "actual" objects (#7633)
This issue still open? We have the same problem over here. Is there a fix already or some workaround?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
You actually also get the partial object even without caching. What is the behavior of Partial objects might look useful for improving database SQL query performance, but mostly are harder to handle in the domain code. If you don't need the whole values of an entity, you might want to use a custom value object that fits to a use case and fetch them with the |
I have the same problem, too. The idea of separately storing of partial entities, like @Amunak suggested above, is interesting. Current
Why not extend it with parameter that contains required entity fieldset for the current query? For example: I see that nothing was done for resolve this problem in future 2.7 and 3.0 (master) branches. It's very sad. |
@Amunak @yura3d @FabianKoestring this is definitely an edge-case that hasn't been anticipated during L2C's design. Not sure if @guilhermeblanco agrees but I'd rather prevent L2C usage for partial queries and recommend you to use the result set cache. That works well since the cache is bound to each query and set of parameters, the only drawback is that it's up to you to control TTL or eviction. |
Again, while not ideal it's better than having this edge case exist and confuse people :) |
I think I am running into the same issue. Question: are DQL-queries cached by default?
and there is no 'setCachable'. I'd like to write a test on this. Can someone show me how to "look into the SLC"? I mean how I can query the SLC cache provider directly to inspect the behaviour. |
This should be easy to fix, DQL Queries have a hint for partial set when a partial query is done. This would need to be checked in the second level query cache during the "save" part and ignored. |
Do you mean I have to set |
This is weird. I looked into it now. cache does show wrong infosI have created such a test case (symfony framework):
However, looking into redis directly, I do see the cache entry for 'A'.
|
@flaushi no, i mean that Doctrine internally needs to check for the partial queries and not store them in SLC. |
There was a check in DefaultQueryCache that prevented partial queries, because they are not supported. However the checked hint Query::HINT_FORCE_PARTIAL_LOAD is optional, so cant be used to prevent caching partial DQL queries. Introduce a new hint that the SqlWalker sets on detecing a PARTIAL query and throw an exception in the DefaultQueryCache if thats found.
* [GH-7633] Bugfix: Partial queries were stored in 2LC. There was a check in DefaultQueryCache that prevented partial queries, because they are not supported. However the checked hint Query::HINT_FORCE_PARTIAL_LOAD is optional, so cant be used to prevent caching partial DQL queries. Introduce a new hint that the SqlWalker sets on detecing a PARTIAL query and throw an exception in the DefaultQueryCache if thats found. * Housekeeping: CS * [GH-7633] HINT_FORCE_PARTIAL_LOAD still needs to be checked. * Housekeeping: Fix CS
Merged in #8050 |
Bug Report
Summary
When using partial objects and second-level cache, the partial objects can get cached and then they get retrieved from the cache instead of querying for the "full" object.
Current behavior
Doctrine doesn't properly recognize query as fetching a partial object, caches it and then later when asked to query the actual object it only retreives the partial from cache.
How to reproduce
The following snippet would save a partial object to your second-level cache:
Then later running this code:
$real
would actually contain only the partial object data - property$real->field2
would be null and if you could compare the$partial
and$real
objects you would notice that they are essentialy the same.Expected behavior
Ideally Doctrine would cache partial objects separately. While you could argue "why use partial objects when you cache the actual objects anyways and save on speed there" they are great for optimizations and in some cases you don't want to load hundreds of potentially big objects as a whole when you need only a small portion of them.
However at the very least it should recognize that the query above is indeed a partial query and throw CacheException - as it does when you modify the snippet like this:
Obviously that makes the query unusable as it now throws an exception, so the actual solution is to just not mark it as cacheable.
No matter what solution will be implemented I would strongly advice to also mention this caveat of partial objects in their documentation - there is no mention of them not being cacheable anywhere.
Writing this I realized that this bug has probably the same cause as #2094. However this is an important and annoying edge case that proved hard to debug and I feel like it should be documented.
Also as a side note, how the hell is this bug not fixed after 8 years? It seems pretty major.
The text was updated successfully, but these errors were encountered: