-
Notifications
You must be signed in to change notification settings - Fork 11k
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
[5.8] Prevent unnecessary JSON UPDATE queries on MySQL #28029
Conversation
I don't particularly think the code overhead of fixing this is worth it for a fairly minor "bug". |
When logging or auditing the model updates, it's spamming and it creates many unnecessary records so it's better to find a better way to handle it than ignoring it at all. |
You can bypass this bug if you cast JSON attribute as object instead of an array. |
@sigismund This saved my life, I was about to write a function to deeply sort the object before an update as I was using the isDirty check to recompute some other models and it was always true |
This is not fixed for AsCollection |
MySQL normalizes JSON strings by adding a space between key and value (
"foo":"bar"
→"foo": "bar"
) and sorting the keys. This can prevent Eloquent from detecting equivalent values and causes unnecessaryUPDATE
queries:For
collection
andobject
casts, a simple value like['a' => 'foo']
already causes this issue: Due to the additional whitespace,$current === $original
fails and the createdstdClass
/Collection
objects aren't identical.We can fix this by recursively sorting the keys on the current and original value before comparing them. To minimize the overhead, this only happens when the previous comparisons fail.
This PR doesn't apply to nested objects, but they are probably rather rare.
In Laravel 5.9, we could make
sortKeys()
(optionally) recursive and removesortKeysRecursively()
.Fixes #27946.