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.  [ 11 posts ] 
Author Message
 Post subject: How to sort an NH PersistentGenericBag
PostPosted: Thu Jun 15, 2006 8:21 am 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
I need to sort the child object collection in a standard parent/child collection.

When I read a child object collection I cant use the "order-by" clause of the one-to-many bag because I am sorting by values retrieved elsewhere (through a many-to-one relationship from the child object). As far as I can tell, the "order-by" clause is passed straight thru to SQL and I can't put relationships, etc. in there.

So, I want to sort the collection after reading it. However, it is a lazy collection (IList) and doesn't support the Sort method. Also, the actual type is PersistentGenericBag, because it is a lazy NH collection.

What is the best way to sort these objects? Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 10:00 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
there are two methods that i know of; the first is using an HQL query to perform the order.

Code:
"from Parent p where p.Property = :Property order by p.CollectionOfChildren.ChildProperty asc"

the second is to implement IComparable in the child entity class and use the System.Collections.ArrayList.Adapter(parent.CollectionOfChildren).Sort() method. not as effecient as sorting in SQL but will get you what you want.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 10:39 am 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Thanks for the reply. I didn't know about the Adapter.

I wonder if there is a generics version of the Adapter, since I actually have IList<Foo> and not IList. There doesn't seem to be a List<T>.Adapter. Oh well, I guess I can write my own easy enough...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 11:25 am 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
Yeah, Adapter is good to know about. I would assume there would have to be a way to do it with generics. If there isn't, that seems like a somewhat major oversight. Microsoft seems to use interfaces a bit less than the Java folks do. What surprises me is that I would have expected a static Sort() method that takes an IList somewhere. Maybe there is one, but, I haven't found it yet. It seems like I've ran into other deficiencies with generics too although I can't think of anything offhand. My guess is that they'll proably polish up the generic collections in the next version of .NET.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 11:41 am 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
Oh yeah, one other thing, that's been bothering me about .NET in comparison to Java is it's lack of a ListIterator class. This class in Java allows you to iterate over a list, and remove items while iterating over it.

It seems like there should be an easy way to create a List<T> from an ArrayList too. It's easy enough to just use a for loop to do it, but, it seems like there should be a method that does this for you.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 11:45 am 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Yeah, I ended up writing my own adapter. Kind of silly. The thing I am wondering about is if the list.Clear() and the list.Add() methods will confuse NH into thinking I am modifying the objects in this collection, but really I am just re-ordering them. Any thoughts?

Code:
      private static void SortObjects<T>(IList<T> list)
      {
         ArrayList arr = new ArrayList();

         foreach (T t in list)
         {
            arr.Add(t);
         }

         arr.Sort();

         list.Clear();

         foreach (T t in arr)
         {
            list.Add(t);
         }
      }


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 11:59 am 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
In theory, I think what you're doing should work OK.

What I was thinking is maybe you could do is something like the following. However, in this case, I think it will screw things up because I think NHibernate may store other references to the collection. I could be wrong on that, but, I seem to recall having some issues when trying to do something like this way back when with the Java version of Hibernate.

Code:
List<Child> l = new List<Child>(p.CollectionOfChildren);
l.Sort();
p.CollectionOfChildren = l;

Usually, I just initialize my collection once and don't change it after that.

I guess you could do something like this though.

Code:
List<Child> l = new List<Child>(p.CollectionOfChildren);
l.Sort();
p.CollectionOfChildren.Clear();
p.CollectionOfChildren.AddRange(l);


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 12:57 pm 
Senior
Senior

Joined: Sat Mar 25, 2006 9:16 am
Posts: 150
Thanks for the information. It is indeed interesting if replacing the collection object would interefere with operation of NH. I'm guessing it works fine since once the collection has been initialized, NH no longer needs its proxied object?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 1:45 pm 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
I thought I read at some point that you weren't supposed to replace the collection or something, but, it may be the case that I'm just confused and misrembering. I guess the thing to do at this point would be just try it out and see if things go awry. That's usually the most authoritative way to figure things out. ;-)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 15, 2006 1:54 pm 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
you are right jemiller, you aren't really supposed to be replacing the entire collection. but i agree; generics are a new thing here and anything can be tried but for time and effort.

-devon


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 22, 2006 3:46 pm 
Newbie

Joined: Fri Jun 02, 2006 2:33 pm
Posts: 2
devonl,

That little bit about,
System.Collections.ArrayList.Adapter(parent.CollectionOfChildren).Sort() method

is precisely what I needed.

Nice, and thank you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 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.