Skip to content

Refactor AttachRelationships: prevent reattachment, support implicit remove #502

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

Closed
maurei opened this issue Apr 30, 2019 · 1 comment · Fixed by #518
Closed

Refactor AttachRelationships: prevent reattachment, support implicit remove #502

maurei opened this issue Apr 30, 2019 · 1 comment · Fixed by #518
Assignees

Comments

@maurei
Copy link
Member

maurei commented Apr 30, 2019

Problem

Consider the following scenario

  • Person one-to-one Passport
  • initial condition of the database:
    • two Persons items: person1, person2.
    • only one Passport item: passport
    • foreign key PassportId on person1 equals id of passport

We now do a PATCH /people/2 and attempt to update the relationship of person2 by relating it to passport. What I would expect it to do is to perform an implicit remove of the old relationship: implicit in the sense that the relationship with person1 is updated even though it was never explicitly mentioned in the original request.

Right now, it results in a 500 because a foreign key constraint is violated. This is because person1 is already related to passport and the implicit remove is not taken care of, resulting in a FK constraint error.

Update bug reproduced in this test

Issue: a 500 is not acceptable.

Solution

Two options

  1. Don't actually do the implicit remove, but return a 400 Bad Request with a body stating that the relation between person1 and passport should be removed first, thus more or less reflecting the foreign key constraint error message that is generated by the database~
  2. handle these situations intelligently in the repository layer. The repository layer would take care of breaking the relationship between person1 and passport before relating person2 to passport. EF Core can handle this trivially if we just attach person1 to the dbContext before saving the changes (by just loading the Person relationship of passport). Right now that doesn't happen.

I prefer the second option.

[EDIT]

This goes wrong for CREATE, UPDATE for both one-to-one and one-to-many. All goes in a similar way: the entity on the inverse navigation property needs to be attached. This means that the fix is not specific to one particular "pipeline", but the AttachRelationship method which is called in all involved pipelines needs an upgrade:

maurei added a commit that referenced this issue Apr 30, 2019
@maurei maurei added this to the v4.0 milestone Apr 30, 2019
@maurei maurei self-assigned this Apr 30, 2019
@maurei maurei added the bug label Apr 30, 2019
maurei added a commit that referenced this issue Apr 30, 2019
@maurei maurei changed the title FK constraint violation with one-to-one update FK constraint violation with one-to-one update and implicit remove Apr 30, 2019
@maurei maurei changed the title FK constraint violation with one-to-one update and implicit remove FK constraint violation with one-to-one update/create and implicit remove Apr 30, 2019
@maurei maurei changed the title FK constraint violation with one-to-one update/create and implicit remove Refactor AttachRelationships to attach entities on inverse navigation properties Apr 30, 2019
@maurei maurei changed the title Refactor AttachRelationships to attach entities on inverse navigation properties Refactor AttachRelationships: prevent reattachment, support implicit remove Jun 7, 2019
@bart-degreed
Copy link
Contributor

For reference, the next picture shows uniqueness constraint violations for one-to-one relationships.

one-to-one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

2 participants