-
Notifications
You must be signed in to change notification settings - Fork 936
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
Partially port Hibernate's current field interceptor mechanism #1947
Partially port Hibernate's current field interceptor mechanism #1947
Conversation
ac76724
to
7f88130
Compare
1d87c46
to
add4a82
Compare
This comment has been minimized.
This comment has been minimized.
Not anymore as the interceptor is now injected from the entity creation so the interceptor will receive a proxy for a |
On second thought the
In order to correct that we would have to port the Hibernate behavior for |
The fact that the proxy id is retrieved immediately is an implementation detail. I do not think The normal behavior of a When only the association id is loaded, it will cause a db access: the property has to be considered non-initialized.
I hope this is still a hidden implementation detail: I mean, when reading the property, we still get an unproxied entity. Otherwise the purpose of In such case, when an user put an uninitialized proxy in a no-proxy property, this is still an edge and a bit weird case. I have not check the behavior of the property in such case by the way, but if, when reading it afterwards, it yields an hydrated un-proxied entity instead of the proxy the user has assigned to it, that would be a debatable behavior. It should yield back what the user has assigned to it instead, for not breaking the unicity of the entity when working with a single session. |
I have "resolved" my first comment because it was based on a false assumption.
All this was about the case where the user assigns a proxy to a In such case, I agree the About whether the |
Fine by me.
This is exactly how the current behavior of this PR works.
Of course, this is the whole purpose of
Currently, NHibernate will initialize the entity on set as it does not return earlier when the
I am ok with this behavior but we would still need to list this as a breaking change as currently the proxy will be initialized on set. This behavior could be achieved by checking if the session is set on the interceptor or not as the session is set in the In Hibernate when setting a proxy on a initialized
but in the following scenario the behavior is quite unexpected (at least for me):
I think that is not how it should work as the |
As explained in this comment, I do not think this PR should change the property behavior of yielding the unwrapped entity instead of the proxy assigned by the user to the property.
So, as you write, small breaking change: assigning an uninitialized proxy to a |
With the latest commit the interceptor was modified to yield a proxy instead of unwrapping it when it is set by the user. |
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.
For some reasons, dd9204b has broken the field-interceptor proxy serialization. I have not investigated why.
Actually this commit somehow broke the following test: |
As already discussed, the Hibernate field interceptor works differently that the current NHibernate's one and this PR is aimed to shrink the differences between the two. The most important difference that this PR ported is when the field interceptor is injected. In NHibernate the interceptor is injected after the entity is hydrated and in Hibernate it is injected right after the entity is instantiated. By injecting the interceptor at the entity creation the interceptor will track all uninitialized properties and we don't need to calculate them after the entity is initialized, which is what #1922 currently does. Another mechanism that this PR aligns is the ability to retrieve an initialized unwrapped proxy after the session is closed:
The current code will throw as the payment was not set upon initialization.
Also, another thing that was done in this PR and does not work in Hibernate is to update the state of the initialized lazy="no-proxy" properties when they are set, for example:
I think it is more correct to update the state as otherwise we are not able to detect if the
Payment
is really initialized or not.There is still some differences that this PR does not address:
The above code will produce 3 queries:
a
without containg theb
propertyb
propertyb
entityI think that NHibernate behavior for lazy="no-proxy" is more practical/usefull as I don't see the point of not selecting the id of
b
as the main point of lazy propeties is to avoid expensive formulas or columns with large data.The breaking change of this PR is the changed behavior of
NHibernateUtil.IsPropertyInitialized
which now returns the actual initialization state for the property.EDIT:
By injecting the interceptor at the entity creation the issue of fetching a property mapped as lazy="no-proxy" for an entity that is not yet loaded is now working (#1267 second test).
Possible breaking change: assigning an uninitialized proxy to a
no-proxy
property will no more trigger the proxy initialization. Moreover, reading the property afterwards will no more unwrap the assigned proxy, but will yield it.