Skip to content
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 getting of initialized proxies for no-proxy associations outside of session scope #3347

Merged
merged 4 commits into from
Jul 4, 2023

Conversation

bahusoid
Copy link
Member

@bahusoid bahusoid commented Jul 2, 2023

Fixes #1267

@bahusoid bahusoid changed the title Fix handling of initialized proxies for no-proxy associations outside of session scope Fix getting of initialized proxies for no-proxy associations outside of session scope Jul 2, 2023
@fredericDelaporte fredericDelaporte added this to the 5.5 milestone Jul 2, 2023
@bahusoid
Copy link
Member Author

bahusoid commented Jul 3, 2023

I see a test case that I don't understand. Not related to this change but about no-proxy SetUninitializedProxyShouldNotTriggerPropertyInitialization:

[Test]
public void SetUninitializedProxyShouldNotTriggerPropertyInitialization()
{
using (var s = OpenSession())
{
var order = s.Get<Order>(1);
Assert.That(order.Payment is WireTransfer, Is.True); // Load property
Assert.That(NHibernateUtil.IsPropertyInitialized(order, "Payment"), Is.True);
order.Payment = s.Load<Payment>(2);
Assert.That(NHibernateUtil.IsPropertyInitialized(order, "Payment"), Is.True);
Assert.That(NHibernateUtil.IsInitialized(order.Payment), Is.False);
Assert.That(order.Payment is WireTransfer, Is.False);
}
}

Why setting not initialized proxy leaves property initialized and do return proxy on property access. It doesn't look right to me.

Setting not initialized proxy should mark property as not initialized and trigger entity initialization on property access returning unwrapped proxy. Any objections?

@fredericDelaporte
Copy link
Member

fredericDelaporte commented Jul 3, 2023

Well, for simplicity, I guess, but also because user intend is not clear in such case, and yielding something else that what the user has affected could also be unexpected for the user.

The user has mapped the Order.Payment as "no-proxy", but then assign to it a proxy? Actually a strict behavior would be to throw some InvalidOperationException in such case, but that would be a breaking change. And that could forbid some valid use cases hard to handle otherwise.

Yielding an unwrapped proxy on subsequent get could cause some mess with the user own handled state: how can we ensure the user does no more hold any references to the original proxy? Now the same entity would be represented by two instances sent back to the user by the same session? That breaks one major contract of the session which strives very hard to always yield the same instance for an entity.

So, better leave this in its current state in my opinion.

@bahusoid
Copy link
Member Author

bahusoid commented Jul 3, 2023

The user has mapped the Order.Payment as "no-proxy", but then assign to it a proxy?

He simply doesn't know it assigning some other lazy association. "order.Payment = invoice.Payment;" Also I see no restrictions on assigning proxy directly. From my understanding no-proxy just ensures to retrieve no proxy on property access (which is currently broken in case proxy is set by user)

Now the same entity would be represented by two instances sent back to the user by the same session?

Not sure I get it correctly. Did you mean proxy and unwrapped proxy? We already have such situation if proxy is loaded directly by user or with other entity before loading no-proxy owning entity:

[Test, Ignore("This shows an expected edge case")]
public void GhostPropertyMaintainIdentityMapUsingGet()
{
using (ISession s = OpenSession())
{
var payment = s.Load<Payment>(1);
var order = s.Get<Order>(1);
Assert.AreSame(order.Payment, payment);
}
}

Anyway, I'm not planning to fix it any time soon. Just a thought.

@bahusoid bahusoid enabled auto-merge (squash) July 4, 2023 13:48
@bahusoid bahusoid merged commit 770b365 into nhibernate:master Jul 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NH-3047 - Lazy=no-proxy ignores join fetch
3 participants