-->
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: Custom Collection instead of using IList
PostPosted: Mon Jul 10, 2006 10:40 am 
Newbie

Joined: Mon Jul 10, 2006 10:21 am
Posts: 12
Hi,

is there a solution to use custom collections based on System.Collection.ObjectModel in objects instead of using IList or ISet?

I want to provide some additional functionality like "Cat.Kittens.EnumIll()"?

I have searched for it, but havent find any usefull result.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 10, 2006 2:50 pm 
Pro
Pro

Joined: Fri Nov 19, 2004 5:52 pm
Posts: 232
Location: Chicago, IL
I could be wrong on this, but, I think the answer is no because when NHibernate reads objects out of the database and it creates collections, it uses it's own custom collection classes. I think it does this in order to support lazy loading.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 10, 2006 3:52 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
In the SVN version you can create your own collections but it's a bit tricky. Take a look at the UserCollectionType and the related test. In 1.0.x using custom collections is not possible.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 10, 2006 5:14 pm 
Newbie

Joined: Mon Jul 10, 2006 10:21 am
Posts: 12
Hmm,
System.Collection.ObjectModel.KeyedCollection<>, System.Collection.ObjectModel.Collection<> and System.Collection.ObjectModel.ReadOnlyCollection<>
can be used as wrapper for IList ore IDictinary Collections. If you pass a IList to base Constructor of Collection<> the List isnt created new.

Cant nHibernate inherit this collection ore pass its owen representation to the base constructor? I think thats possible.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 11, 2006 4:09 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Yes it is possible, but how is it better than the current approach? Even if NHibernate's collections derived from other classes than they currently do, you would still have to write a UserCollectionType to be able to add custom methods to your collections.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 13, 2006 9:21 am 
Newbie

Joined: Mon Jul 10, 2006 10:21 am
Posts: 12
It seems UserCollectionType isnt the right way because the model havent to know the use of nhibernate.

The only solution that i find is to use this:

Code:
class Cat
{
.....
     private IList<Cat> kittens = new List<Cat>();

     public CatCollection Kittens
     {
          get
          {
                return new CatCollection(kittens);
          }
     }
}

class CatCollection : System.Collection.ObjectModel.Collection<Cat>
{
     public CatCollection(IList<Cat> cats) : base( cats )
     {
     }

     public IEnumeratable<Cat> EnumIll()
     {
          .....
     }
}


In this case NHibernate maps the private kittens IList.

Did you see any problem with this solution that i couldn see at the moment?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 14, 2006 10:31 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
But the model wouldn't have to know about NHibernate, that's the whole point!

Anyway, your approach will work too, as long as you tell NHibernate to access the collection directly (using access="field...").


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 14, 2006 12:24 pm 
Newbie

Joined: Mon Jul 10, 2006 10:21 am
Posts: 12
sergey wrote:
But the model wouldn't have to know about NHibernate, that's the whole point!

Anyway, your approach will work too, as long as you tell NHibernate to access the collection directly (using access="field...").


Yes but this solution had a problem. I if i use this collection in HSQL i have to use "kittens" not the public property "Kittens".

I think't about it. IList ISet and something else are a liddle bit generic. Ive looked at the implementation of System.Collection.ObjectModel.Collection . It is only a wrapper. It has an internel Field with name items of type IList and all Methods are using this underling IList.

NHibernate can detect that Kittens is derived from Collection und create an instance of this collection with default constructor when its null and then redirect NHibernate to the private items field of the Collection.

Its not a "must have" feature, but i could increase the capabilities of nHibernate.

If you say its intresting and its possibility, then i can try to write a patch for it. But i have to know about the sticking points.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 14, 2006 1:17 pm 
Beginner
Beginner

Joined: Wed Dec 28, 2005 3:14 pm
Posts: 29
I have the same issue as Ianwin's.
I don't fell safe to expose mutable collections with which associations are maintaned with. Our client programmers are tempt to modify the collection directly. It's just not safe to expose something mutable that is not suppose to be mutable by any class other than the holder.
So I normally will wrap the collection with a ReadonlyCollection wrapper ( not the System.Collection.ObjectModel.Collection which can only wrap IList), and expose only that wrapper and let NHibernate access directly to the field.
The issue is that I have to use a field name of the collection in HQL.
However, I don't think adding a special support to System.Collection.ObjectModel.Collection will be helpful. First, it's not ellegant, and second System.Collection.ObjectModel.Collection can only support IList that is <bag> and <List>, what about <set> and <map>?

I do like the new .net 2.0 property permission which allow you to set the setter as private so that only NHibernate and holder can modify the property, while the outside can only read it.
Is there any possibility that Nhibernate can provide a set of collection that only Nhibernate and the holder (class where the collection is declared) can modify it? Shall it throw an exception when the outside try to add/remove/clear its item? Seems a little bit against the basic OO principle: A class should always behave the same no matter what the caller is. I am just thinking aloud.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 14, 2006 2:05 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Quote:
if i use this collection in HSQL i have to use "kittens" not the public property "Kittens".


No. Look at the naming conventions for access="field", like access="field.camelcase". If you use, for example, <property name="Kittens" access="field.camelcase" />, then NH will use field named kittens to access the property, but you can still use Kittens in HQL.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 14, 2006 4:42 pm 
Newbie

Joined: Mon Jul 10, 2006 10:21 am
Posts: 12
Ok ive tryed it. This solution works. I didnt know that field is combinable with camelcase.

And what if youre extend lesi.Collections to support extendeble collections that nHibernate can handle?


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.