Yes basically you are right but I just find it to be a lot of plumbing
if I in my DAO (Reposoitory) need to go through all the objects returned
from NHibernate and replace those with proxies where I need my custom
lazy loading.
But I looked further into why my custom ReflectionOptimizer was not
called for components, bascially because it's interesting to lean from
reading other peoples code and not because I expected to find a quick
solution, but I actually found something that might be a bug or it might
just be left like that intentionally. It should be noted that we are
currently using NH 2.1.0 on our project.
In PocoComponentTuplizer.BuildInstantiator there are the following code:
if (optimizer == null)
{
return new PocoInstantiator(component, null);
}
else
{
return new PocoInstantiator(component,
optimizer.InstantiationOptimizer);
}
My problem was that even though I had enabled the optimizer the
optimizer was always null here. Looking further I could see that the
optimizer is set in the constructor of PocoComponentTuplizer
if (hasCustomAccessors ||
!Cfg.Environment.UseReflectionOptimizer)
{
optimizer = null;
}
else
{
optimizer =
Cfg.Environment.BytecodeProvider.GetReflectionOptimizer(componentClass,
getters, setters);
}
However BuildInstantiator is only called from the constructor of the
class that PocoComponentTuplizer inherits from:
AbstractComponentTuplizer. So basically then BuildInstatiator is called
before it's checked if the reflection optimizer should be used. Maybe
it's a bug or maybe it's intentionally left like this, but then at least
there is code that is obsolete in the BuildInstantiator as it can never
be reached.
What I then did was to call BuildInstatiator again in the constructor of
PocoComponentTuplizer after setting the optimizer:
instantiator = BuildInstantiator(component);
One line of code extra and then suddenly all of my unit tests for my
custom lazy loading became green. :-)
regards Henrik Uffe Jensen
On 5/26/2010 1:20 PM, Fabio Maulo wrote:
NH is not a DAO.
You can use it as a DAO in some cases but NH is not designed to be a DAO.
In your DAO you should load info. from NH and from the other
external-service and then populate your object.
There are others ways as ObjectsFactory, Tuplizer, and/or your
special ProxyFactoryFactory but... as said, it is the hard way.
On Wed, May 26, 2010 at 6:52 AM, Henrik Uffe Jensen <[email protected]
<mailto:[email protected]>> wrote:
Hi
In a solution I'm working on I have quite a lot of objects mapped as
components where only the id is in my local database and other
properties of the object is stored behind a service boundary (so need
to make a service call with the id to get the information).
So I want to implement some custom lazy loading because in the case I
don't need the other properties than the id on those objects then I
don't want to make the service call.
As I'm using Windsor Container anyway in the solution, however so far
not for my domain objects, then my idea was to create an interceptor
and then let it react on the getters to load the data from the service
dynamically. And I then used NHibernates IInterceptor.Instantiate to
resolve my objects from the container if present and otherwise just
return null and let NHibernate construct the object.
And in my initially test this also worked fine. But it turned out now
that it was only because I was testing my custom lazy loading directly
on entities mapped as a class not as a component.
Apparently instantiation of components do not seem to go through
IInterceptor.Instantiate. Is my observation correct?
I then tried with a custom Bytecoderprovider as described in this post
by Fabio:
http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html
But again it works fine for entities mapped as classes but components
seem to be instantiated differently. Is my observation correct again?
So are there some way to hook into the process of instantiation of the
components that I have just not found?
Or is there a completely better way of getting he behavior I'm looking
for? I'm thinking of skipping my current path completely and then
looking into custom accessor for the custom lazy loading instead, but
It's just sad as I was so close on the current path. If just component
construction went through IInterceptor.Instantiate or CreateInstance
of the ReflectionOptimizer then it would have worked.
regards
Henrik Uffe Jensen
--
You received this message because you are subscribed to the Google
Groups "nhusers" group.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
To unsubscribe from this group, send email to
[email protected]
<mailto:nhusers%[email protected]>.
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.
--
Fabio Maulo
--
You received this message because you are subscribed to the Google
Groups "nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.