nhibernate-core icon indicating copy to clipboard operation
nhibernate-core copied to clipboard

NH-3146 - Allow AccessOptimizer to work with BackrefPropertyAccessor and IndexPropertyAccessor

Open nhibernate-bot opened this issue 7 years ago • 0 comments

cremor created an issue:

It would be great if the usage of a BackrefPropertyAccessor (non-inverse collections) or IndexPropertyAccessor (lists) wouldn't prevent the usage of the AccessOptimizer.

This is currently the case because the PocoEntityTuplizer and PocoComponentTuplizer set the optimizer to null if a non-optimizable Accessor (which are all except for BasicPropertyAccessor and FieldAccessor) is found in the entity/component.

I can think of two solutions for this:

  1. Change the meaning of IOptimizableGetter.Emit() to emit IL-code for GetForInsert() instead of Get(). This won't affect currently optimzed Accessors because they all do the same in GetForInsert() and Get(). It would be needed to add the two additional parameters of GetForInsert() (mergeMap and session) to AccessOptimizer.GetPropertyValues() and to the GetterCallback. Callers that just need the previous behaviour of Get() can pass null to both. Then it would be possible to emit the IL-code needed to execute the same code as the non-optimized GetForInsert() executes. Finally change the CanAccessThroughReflectionOptimizer property of the now optimized Accessors to return true and it should work.

  2. Easier solution, that doesn't require complex IL-code: Do not clear the optimizer in PocoEntityTuplizer and PocoComponentTuplizer. Instead create a second flag "hasCustomGetForInsertAccessors". In GetPropertyValues() and SetPropertyValues() check the flag "hasCustomAccessors" instead of the optimizer. In GetPropertyValuesToInsert() check the new flag "hasCustomGetForInsertAccessors" instead of the optimizer. To calculate this new flag a new property in the IPropertyAccessor interface and the Property class would be needed (could be named "CanAccessGetForInsertThroughReflectionOptimizer"). While there, the property Property.IsBasicPropertyAccessor could finally be renamed to CanAccessThroughReflectionOptimizer to make it less confusing. Finally implement the IOptimizableGetter and IOptimizableSetter interfaces for BackrefPropertyAccessor and IndexPropertyAccessor to just return the static field "Unknown". Both would then return true for CanAccessThroughReflectionOptimizer and false for CanAccessGetForInsertThroughReflectionOptimizer. That way default get and set operations would be optimized and only GetForInsert() would need reflection calls.

I could create a pull request for this (altough not in the next few weeks) if it would be accepted and merged.


cremor added a comment — :

Any thoughts on this from the NHibernate development team?


Alexander Zaytsev added a comment — :

<~cremor> can you please provide a test case or complete pull request?

nhibernate-bot avatar Oct 12 '17 12:10 nhibernate-bot