I've got an entity that I need to query a couple different ways.
Entity
- ID
- Name
- IList<SubItem>
- (more than one collection)
1st use case
- when showing a list of these entities, I need to query them without the
collections.
2nd use case
- when queried by ID, I need to return the entire graph, collections and all
To accomplish the latter, I map the collections: not lazy + inverse
To accomplish the former, I would typically use a ProjectionList.
-- but when I use a projection, NH throws an exception .. trying to convert
a KVP[] to my entity. idk what that's about ..
---- I've run into similar issues with projections (though that was using a
projection while using query cache, very similar but diff error)
So .. what I've done in the past (and still in other areas)
-- map the collections as lazy ..
-- query the entities [.. criteria.List(); ]
-- Commit transaction [ trans.Commit(); ]
-- before serializing out / accessing, set the collections to null to get
rid of the NH proxy that would initiate the lazy fetch. [
rValue.ForEach(x=>x.Collection=null;... ) ]
The problem with doing this, is that preferably (when i want to return the
collections) I want them JOIN fetched (a single query)
-- But if I map them as Lazy I will *ALWAYS get N+1* *using session.Load().*
---- I can get around this by using a criteria (set FetchMode.Join) rather
than session.Load .. but then it doesn't hit the cache like Load/Get does.
So, obvious next choice is .. just map the entity under the assumption
that it will handle the session.Load() and fetch with a Join
-- not lazy
-- inverse
-- fetch JOIN
-- session.Load() gets me the entire graph. perfect!
The problem with this is that when getting a list of the entities I get
different behavior (than the hack above)
-- It seems when I set FetchMode.Lazy in the criteria, it will ALWAYS fetch
those no matter how I try to keep it from doing so.
-- criteria.SetFetchMode("CollectionName", FetchMode.Lazy);
-- criteria.List()
-- trans.Commit() <-- unlike above, NH issues the n+1 fetch for the
Collection here
It was my understanding that LAZY means that until the property is *accessed
*NH will not issue the select for its value/child properties other than the
ID.
-- this is why the above hack works for Lazy in the mapping as opposed lazy
in the criteria.
---- The collections are only read when I serialize them across the wire.
Is this a bug?
Can anyone see a way around this?
For now I will be using criteria to query by ID, rather than Load(). This
just seems very ugly to me, and doesn't take advantage of cache (unless
that assumption is incorrect?)
------
Joe Brockhaus
[email protected]
------------
--
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.