Stale cached value returned where(...)->first()
aaroncameron opened this issue · 11 comments
Describe the bug
Requesting the first (and unique) result with Model::where(...)->first() returns an old, incorrect result,
Eloquent Query
MyModel::where(['a'=>1,'b'=>2])->first(); // returns an old result
MyModel::where(['a'=>1,'b'=>2])->get()->first(); // returns the correct result.Environment
- PHP: 8.1.2
- OS: Ubuntu 22.04
- Laravel: 10.15.0
- Model Caching: 0.13.4
Additional context
That the result in my test case is unique may or may not be relevant. Have not constructed a test where it is not to confirm.
There is in the above a unique key across a,b. The result is not simply coincidentally unique, but is by definition.
Just to update with another case discovered, for non-unique result sets, different symptom and way to trigger:
MyModel::where('cond', true)->first(); // returns no results
MyModel::where('cond', true)->get()->first(); // returns the correct result
MyModel::where('cond', true)->limit(1)->get()->first(); // also returns no results.
thanks for the added details Aaron. These should not be happening. I will take a look at the tests later today and see what's going on.
I've been doing some testing and have found the following:
- queries using the
->where([ <multiple conditions> ])syntax are not caching correctly, when compared to->where(...)->where(...) -
seems to return the same results as expected.
$author = (new Author) ->where("id", 1) ->orWhere("id", 2) ->first(); $author2 = (new Author) ->where("id", 2) ->orWhere("id", 1) ->get() ->first();
Could you send me the full query you are having issues with? Perhaps that will give me some additional clues to look for.
Sure thing. I don't recall the code that was the source of my original case any longer, but the example I sent here was contrived anyway. Confirmed, but contrived. The version of the issue I found earlier today I still have though. TL;DR is it looks like the limit causes the cache to fail in some way.
Looks to me like the conditions don't even matter (other than the issue you found).
In all cases I confirmed the working/not working with the cache turned on, then turned the cache off with the query logging on to get the exact query generated.
Working:
DND5ECharacterSheet::where('is_premade', true)->get()->first();select * from `dnd5e_character_sheets` where `is_premade` = ?
-- {"bindings":[true],"time":14.59} Not working:
DND5ECharacterSheet::where('is_premade', true)->limit(1)->get()->first();select * from `dnd5e_character_sheets` where `is_premade` = ? limit 1
-- {"bindings":[true],"time":9.35} Not working:
DND5ECharacterSheet::where('is_premade', true)->first();select * from `dnd5e_character_sheets` where `is_premade` = ? limit 1
-- {"bindings":[true],"time":6.52}