Hi Dan

Lazy BelongsTo:
[BelongsTo(FetchWhen=FetchWhen.OnInvoke)]
public virtual Parent MyLazyParent {get;set;}

NH and WPF bindings: Can you please ask at NH-Users? I don't have the
necessary experience with binding NH entities to WPF controls.

-Markus

2010/7/27 Dan Jasek <[email protected]>:
> The proxy method you describe is how I have implemented the data
> virtualization.
> However, I do not use a conversation to hydrate the objects, I create
> a new SessionScope for each group I need to load.  I did not want to
> use a conversation because, from what I understand, every object
> loaded in the conversation will remain in the first level cache for
> the life of the conversation.  If the user ended up scrolling around
> and displayed the entire tree, then the entire tree would be in the
> first level cache.  This would use much too much memory and defeat the
> purpose of the data virtualization.
>
> As for your argument against auto-eviction.  We don't need to do the
> reference counting ourselves.  That is what the garbage collector does
> best.  When an object gets old you just change the reference in the
> cache to a weak reference.  When nothing in the user code holds a
> reference to the object, it will get GC'd in due time.  In the mean
> time, the object in the cache will act as normal.
> The only sticky point I see off the top of my head is that you never
> want a weak reference in the cache to an object that has been updated
> by the user, but not flushed.  The user code could modify the object,
> then drop it's reference before the object is flushed to the DB.  I
> don't yet know enough about the NH code base to be able to tell if
> this is a big issue or not, but I am guessing it is not.
> From what I understand, this is the primary problem with using long-
> running sessions.  So, fixing this seems like a big win, at least for
> the desktop world.
>
>
> I ran into another issue with NH object proxies.  They do not appear
> to be compatible with WPF.  Specifically WPF bindings can not access
> the actual data through a NH proxy (as created when you set an AR
> class as lazy).  I have added a Self method to my AR base class that
> simply does, "return this;".  That gets a reference to the true
> object, which does work with WPF bindings.  So, for now, every binding
> to a lazy object is going through this Self method.  But I am not
> happy about it.
> The only reason I am using lazy objects is because I can not get a
> BelongsTo reference to lazy load.  If anyone else has gotten a lazy
> BelongsTo, I would love to hear how.
>
> -Dan
>
> On Jul 24, 8:00 am, Markus Zywitza <[email protected]> wrote:
>> Hi Dan
>>
>> for your tree, I recommend a manual proxy that only has the tree
>> structure information and the  id of the object it represents. You can
>> then load all proxies in one go:
>>
>> using (new SessionScope())
>> {
>>   foreach(var item in TreeItem.FindAll())
>>   {
>>     tree.Add(new TreeItemProxy(item));
>>   }
>>
>> }
>>
>> then you create the IConversation and everytime an object should be
>> loaded, it as easy as
>>
>> conversation.Execute(
>> ()=>displayItem(TreeItem.Find(selectedTreeItemProxy.itemId)));
>>
>> As for auotmatic evicting old references:
>>
>> This is a source for hard to find bugs. Within a session or
>> conversation, changes to an entity are tracked automatically. Imagine
>> an object being unused for a lot of time and automatically evicted
>> some time later. Then the code changes it and those changes will never
>> make it to the DB. You have to do reference counting to circumvent
>> this and such isn't simply worth the effort.
>>
>> The problem with lazy loading is that NH-generated proxies keep a
>> reference to the ISession used for originally loading the proxied
>> object. If you change NH to allow reattaching, lazy loading is a
>> no-brainer for AR because we can create sessions on demand if there is
>> none open through a scope or conversation.
>> It boils down to creating NHibernate.ByteCode.ActiveRecord. I started
>> such a project once, but I didn't get any workable results, mainly
>> because the session storage implementation in an abstract NH class
>> used by the bytecode providers is not virtual (grr). If you want to
>> try yourself: Good Luck!
>>
>> -Markus
>>
>> 2010/7/20 Dan Jasek <[email protected]>:
>>
>>
>>
>> > Thanks for the reply.  Sorry I'm getting back to this late.
>>
>> > You mention that a detached object is temporarily attached for DB
>> > operations.  Can you give an example of a circumstance when this would
>> > happen.  I can't find any mention of re-attachment in the
>> > documentation or code.  From what I understand of NH, the only time an
>> > object needs to perform DB operations is in a lazy scenario.  And as
>> > you mentioned, these just throw exceptions instead of attempting a re-
>> > attach.
>>
>> > I seem to be able to use detached objects with lazy loading OK.  I
>> > just re-attach them to a session when I access something that may not
>> > yet be hydrated.  It would be nice if AR did this automatically
>> > though.  This is the method I wrote to do this:
>> > public void Reattach() {
>> >            if (!holder.ThreadScopeInfo.HasInitializedScope)
>> >                throw new Exception("Cannot reattach AR object.  No
>> > open Scope.");
>> >            holder.CreateSession(typeof(T)).Lock(this,
>> > NHibernate.LockMode.None);
>> >        }
>>
>> > The only problem with it is that it will throw an exception if the
>> > object is already attached to a session.  That is why I asked about
>> > detecting if an object is currently attached to a session.  I would
>> > like to add a check before I attempt the re-attachment.  But looking
>> > deeper into NH, I don't think it is currently possible.  It looks like
>> > the proxy infrastructure is a little too transparent.  You are unable
>> > to ask this sort of meta-questions about NH objects.
>>
>> > If anyone is interested in my project:
>> > I will be going with AR for my project.  The maturity, performance and
>> > features of NH coupled with the ease of use of AR make it a pretty
>> > easy choice.  There are definitely some warts however, neither project
>> > was designed for the peculiarities of GUI use.  I guess the desktop
>> > jockeys are not as cool as the web dudes anymore.
>>
>> > As I mentioned before, my primary concern is the display of a large
>> > tree structure in a list view which supports data virtualization.  I
>> > have decided to simply use detached objects for this.  There should
>> > not be any lazy loading issues with this particular implementation.
>> > The data virtualization is handled by light-weight proxy objects that
>> > know the identity of the AR object that they wrap.  Once the proxy
>> > objects are generated there will be no need to walk the tree.
>> > So, the only issue is stale detached objects.  To solve this, I keep a
>> > list of currently displayed objects and re-load them when required.
>> > The OnUpdate hook makes this relatively easy.  No other process will
>> > access this DB, so only local mods need to be accounted for.
>>
>> > This is not exactly ideal in my mind though.
>> > So far, there are two additions I could use to AR and NH:
>> > Automatic handling of re-attaching detached objects for lazy
>> > operations.  I can understand why AR does not do this.  It looks like
>> > it would require changes to NH, and custom implementations of the
>> > collection proxies.
>>
>> > The option of a different first level cache.  For web applications,
>> > the build up and tare down of the sessions and their cache must be as
>> > fast as possible and take as few resources as possible.
>> > But in a GUI app I am willing to trade resources and speed for
>> > additional management features.  These features would include:
>> > * Setting cache size and age targets.
>> > * Monitoring object references.
>> > * Auto-eviction of old and unused objects.
>> > * Recovery from failed sessions.
>>
>> > Once I get more familiar with the code base, I may try to put some of
>> > these pieces in place...
>>
>> > -Dan
>>
>> > On Jun 4, 7:31 am, Markus Zywitza <[email protected]> wrote:
>> >> Inline:
>>
>> >> Dan Jasek <[email protected]>:
>>
>> >> > Is there a hook I can connect to to detect when a session has failed?
>>
>> >> If you are using IConversation, then it has an extension point for it as
>> >> shown in the docs.
>>
>> >> > Also, is it possible to determine if an AR object is attached to an
>> >> > active session or not?  I looked through the documentation but didn't
>> >> > see a way.
>>
>> >> Depends. Without conversations or scopes,every AR object is always 
>> >> detached
>> >> and will be only temporarily attached for DB operations. Those detached
>> >> objects however don't support lazy initialisation. You can however use a
>> >> non-lazy-class for detached operations and a lazy class for attached
>> >> operations that map to the same table.
>>
>> >> Using conversation per modification could work.  If I did this, I> don't 
>> >> think there would be any advantage to keeping the read-only
>> >> > display objects in a conversation (I don't need to traverse the web at
>> >> > this point).  I could just leave them as detached...
>>
>> >> Not if you need lazy-loading and you will need it when you have a single 
>> >> web
>> >> of objects. See above for reasons.
>>
>> >> Maybe I could periodically clean the cache myself.  It looks like> 
>> >> NHibernate keeps the cache internal, however.  Do you know of a way to
>> >> > get to it?
>>
>> >> No, but you might want to ask that question at the nh-users list.
>>
>> >> -Markus
>>
>> > --
>> > You received this message because you are subscribed to the Google Groups 
>> > "Castle Project Users" 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 
>> > athttp://groups.google.com/group/castle-project-users?hl=en.- Hide quoted 
>> > text -
>>
>> - Show quoted text -
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Castle Project Users" 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/castle-project-users?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Users" 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/castle-project-users?hl=en.

Reply via email to