-
Notifications
You must be signed in to change notification settings - Fork 934
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
Fix loop detection for associations with fetch="join" mapping #2718
Conversation
0b615a4
to
deaa8f0
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
0f32f3e
to
bfd6887
Compare
255c21e
to
ebd0c2f
Compare
@fredericDelaporte This should address the issue identified in issue #2201 and provide a mechanism for users to disable the loop detection which results in an 1+N case when the entity graph does not have a loop, but the query does. It should be safe for users to disable the loop detection whenever they do not have implicit loops in their entity graph or when they have explicitly set max_fetch_depth. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will do a proper review when I have time but it looks pretty good at quick glance. Some notes:
You shouldn't delete protected members (IsJoinable
) - it's a breaking change. Mark it as obsolete instead. And better to get rid of formatting changes in unrelated places.
You disabled in tests loop detection but reported issue is actually related to old loop detection logic. So reported issue is actually not tested. Please add tests to verify that proper entities are initialized when loop detection is enabled.
Use additionally NHibernateUtil.IsInitialized
in tests to verify that entity is actually initialized. Something like:
Assert.That(p.Parent.Details, Is.Not.Null);
Assert.That(NHibernateUtil.IsInitialized(p.Parent.Details));
@bahusoid With a one-to-one relationship both the old and new behavior always initialize the one-to-one, but they cause additional EntityFetch's to occur. The changes to the JoinWalker are well tested by every other test in the suite. A test that verifies the old behavior vs the new behavior would be very similar to those that failed after modifying it. Those tests only passed due to the side affects of the loop detection and depth-first nature of the old JoinWalker. Those tests did the following:
After the changes to the JoinWalker, Contract.Subcontract.Parties is not initialized but Contract.Parties is. Attempting to delete the Contract after deleting all Parties threw an exception because the Contract could not cascade delete the Parties that were associated with it. If these tests had originally asserted that Contracts.Parties was initialized they would have failed. Swapping steps 1 and 2 above, ensures that the loaded Contract does not have any Parties associated with it and the deletion of the Contract succeeds without issue. |
@bahusoid I'm going to re-order/combine these commits to make it easier to review. I'll let you know when it is ready again. The recent commits revert some of the original modifications to JoinWalker to avoid using the queue for anything but required joins. This eliminates the overhead involved in the simplest of cases where no joins are present. |
…tity graph level by level.
…ML schema definition file.
5043ea4
Fixes #2201