Problem / Motivation

Possibly due to concurrent order saves, I sometimes endup with reference to order items that were removed.

My suggestion is to clear the reference to removed order items on order presave.

See related core issues : #2978521: Remove orphaned (dangling) entity references when an entity is deleted and #2723323: [META] Clean up references to deleted entities.

Comments

jsacksick created an issue. See original summary.

jsacksick’s picture

Issue summary: View changes
jsacksick’s picture

Status: Active » Needs review
StatusFileSize
new1.48 KB

Here's a test demonstrating the failure.

jsacksick’s picture

StatusFileSize
new2.19 KB

The last submitted patch, 3: 3130011-2-tests-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jsacksick’s picture

Note that we should probably open a core issue as well, since it doesn't make sense to allow saving reference to deleted entities.

jsacksick’s picture

Issue summary: View changes

  • jsacksick committed 0e9376c on 8.x-2.x
    Issue #3130011 by jsacksick: Cleanup references to deleted order items...
jsacksick’s picture

Status: Needs review » Fixed

Committed the fix!

amateescu’s picture

Status: Fixed » Needs work
+++ b/modules/order/tests/src/Kernel/Entity/OrderTest.php
@@ -342,6 +342,30 @@ class OrderTest extends OrderKernelTestBase {
+    // Assert that saving the order fixes references to a deleted order item.
+    $order->save();

Core prevents references to non-existent (possibly deleted) items in the entity validation step. It is always necessary to call validate() and check if there any violations before saving an entity.

Given that, I'm not sure the fix is actually fixing anything..

jsacksick’s picture

Well, the test I wrote shows what I'm fixing. If an order item is being removed, the reference to it is never going to be "cleared". It's non controversial and fixed issues I experienced myself on a headless site, with saves over JSON API where the order is being validated.

agoradesign’s picture

@jsacksick you've actually committed new test code + some comments in the order storage, as you've commented out the fix:

//$order->set('order_items', $order->getItems());

  • jsacksick committed 7465cc3 on 8.x-2.x
    Issue #3130011 follow-up: Uncomment the fix.
    
jsacksick’s picture

Status: Needs work » Fixed

@agoradesign: I'm terrible, thanks for watching out :) .

amateescu’s picture

@jsacksick, the problem with the test is that it's not testing a real-world scenario. You need to change the test so it calls validate()/code> before <code>save(), and don't try to save if there are any violations found.

agoradesign’s picture

You're welcome :)

Why isn't that real-world? If the test doesn't lead to having validate() called, why should that be guaranteed in real world? I'm unsure baout that assumption

amateescu’s picture

Status: Fixed » Needs work

@agoradesign, because the entity system does not (and can not) guarantee data integrity if you don't validate an entity before saving it, that's how the Entity API works. Any real world code that calls save() without validating before is broken and needs to be fixed.

jsacksick’s picture

Status: Needs work » Fixed

@amateescu: Well to me the fix is non controversial, there's probably broken code somewhere without a doubt, but at least this will limit the impact of making such a mistake...

And this isn't the only usecase the patch is addressing. If an order item is being deleted, the next time the order will be saved, the reference will remain, and that code fixes that.

Rather than putting this issue to "needs work" endlessly, we should probably. open other issues for the broken code we find :p.

jsacksick’s picture

Related issues: #3130011: Clear broken order items reference on presave.

IMO the best approach to solving these kind of problems is to implement locking.

We have an issue for that (#2656818: Implement optimistic locking for orders), and that's the appropriate fix, however, the patch there is still not "ready", and that I think will "mitigate" the issue a little bit.

amateescu’s picture

Well to me the fix is non controversial

IMO the fix is not ok because it prevents the actual bugs from being discovered at all by hiding the problem under the rug. This means that there are way less chances to find instances of broken code and open issues for them.

And this isn't the only usecase the patch is addressing. If an order item is being deleted, the next time the order will be saved, the reference will remain, and that code fixes that.

If removing an order item outside of a "cart context" is a problem, then the deletion should be prevented by the order item storage.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.