-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: [OnDeserialized] equivalent?
PostPosted: Mon Jan 21, 2008 3:30 pm 
Newbie

Joined: Mon Jan 21, 2008 3:25 pm
Posts: 6
Is there an NHibernate equivalent of [OnDeserialized] (not [OnDeserialization])?

I am working on a project using NHibernate. Many of our business objects have internal collections, where updating the collection causes side-effects in other objects (e.g., a when a one-to-many relationship is modeled as a collection on the “one” side and a back reference on the “many” side, and the relationship requires modifying both sides to keep things consistent) or other objects’ collections (e.g., when a many-to-many relationship is modeled as two one-to-many relationships, similarly with a consistency requirement). Other objects can request the business objects to modify these internal collections, and frequently these internal collections need to be observable (implement INotifyCollectionChanged). There are three approaches that seem at first glance to be viable:

1. Publish the internal collection as a property;

2. Implement the ICollection<T> and INotifyCollectionChanged interfaces on the business object itself, and implement ICollection<T> methods that delegate to the internal collection and fire the NotifyCollectionChanged event as appropriate.

3. Implement AddToXyzzyCollection(), RemoveFromXyzzyCollection, ClearXyzzyCollection(), NotifyXyzzyCollectionChanged, and so forth, methods and properties, and delegate to the appropriate method of the appropriate internal collection.

Alternative (3) is surpassingly ugly, and I believe should be avoided if at all possible.

Alternative (2) seems cumbersome, particularly when a business object has several internal collections—and is unusable if two of those internal collections happen to be collections of a single element class.

Alternative (1) therefore seems most desirable: we publish the collections as a property, and let client objects add and remove elements and collection change observers as they wish. Now, to keep the various collections and references straight, the business object has to itself subscribe to the NotifyCollectionChanged event of the internal collection, so that it can propagate changes as required. (That is, if some client object removes a BaseLocation from a GeographicArea’s collection, I need to clear the GeographicArea property of that BaseLocation.) Similarly, if the business object is to control clients’ abilities to modify its internal collections, the internal collections need to call back to the business object for permission to perform an incipient modification—a “NotifyCollectionAboutToBeChanged” event, if you will.

Now, both of these require the business object to update the internal collection’s delegates. This must happen after the internal collection is constructed. So either (i) the internal collection’s various delegates must survive saving and loading with NHibernate, (ii) the internal collection’s various delegates must be restored by the business object after NHibernate has loaded the object, or (iii) the internal collection must in fact be several collections—delegate lists and the desired collection itself—and each of the delegate lists and the collection itself are separately saved and restored.

I can’t see a way to do (i). I also can’t see a way to do (ii)—a load interceptor delegating to a “hook things up” method in the object is almost possible, but load interceptors are called before construction, rather than after. And I can’t see a way to do (iii)—NHibernate seems not to document a way to save and restore a delegate (a list of methods, rather than objects).

So it seems alternative (3), implement AddToXyzzyCollection() and its many friends and relations, is about the best that can be done. Unless there is some post-load, pre-use hook—the NHibernate equivalent of either IDeserializationCallback or [OnDeserialized]. I can’t find one. Does one exist?


Top
 Profile  
 
 Post subject: Answering own question
PostPosted: Tue Jan 22, 2008 10:18 am 
Newbie

Joined: Mon Jan 21, 2008 3:25 pm
Posts: 6
Apparently, the ILifecycle interface in NHibernate.Classic has an OnLoad method that is what I need. Of course, ILifecycle is deprecated...


Top
 Profile  
 
 Post subject: Use IInterceptor.OnLoad
PostPosted: Thu Jan 24, 2008 8:50 am 
Newbie

Joined: Tue Jan 09, 2007 5:24 am
Posts: 15
Hi - BHetrick.

You could try to use the IInterceptor.OnLoad() method. This method is invoked by NHibernate when it is about to load the object from the database.

I have used this method load data from another system when creating a new object. See: http://forum.hibernate.org/viewtopic.php?t=981259

The nice thing about the IInterceptor is that you do not have to "pollute" your domain model with the ILifeCycle interface.

Hope this helps.
Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 24, 2008 10:35 am 
Newbie

Joined: Mon Jan 21, 2008 3:25 pm
Posts: 6
I believe the inapplicability of IInterceptor.OnLoad() is explained in the original posting.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 27, 2008 11:06 am 
Newbie

Joined: Tue Jan 09, 2007 5:24 am
Posts: 15
Hi BHetrick -

> I believe the inapplicability of IInterceptor.OnLoad() is explained in the original posting.

Well excuse me, but it is a very long post you have written!

> but load interceptors are called before construction, rather than after.

You are almost correct - the instance is created but the values are not assigned to the object yet. It is possible to scan the list of values and do some processing.

In general I would say that if you need some event from an object you need to model it explicitly.

You could also try the collections developed by Brian McCafferty:

http://devlicious.com/blogs/billy_mccaf ... tored.aspx

Maybe you can expand them with the events you need.

Cheers,
Thomas


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.