Yep, tried FetchWhen.OnInvoke. Doesn't seem to work and judging from a google search I'm not the only one with this problem. These are definitly NH issues, I will ask over there. Thanks for the help.
I'll let you know when I get more serious about working on those changes... -Dan On Jul 27, 2:26 pm, Markus Zywitza <[email protected]> wrote: > 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 > > ... > > read more »- 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.
