-->
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.  [ 9 posts ] 
Author Message
 Post subject: automatic properties (.Net 3.5)
PostPosted: Mon Mar 17, 2008 6:22 am 
Newbie

Joined: Mon Mar 17, 2008 6:07 am
Posts: 5
I'm thinking of using nHibernate on a new project and having read some of the documentation I realise that nHibernate supports automatic properties and I also understand how nHibernate used the private variable ('_XXX') with previous versions of .Net to set the property value via reflection.

Some of the domain model entities will not expose a public setter automatic properties they will use method such as 'Add' or 'AddRange' - these will generally be entity properties that represent collections. The reason for this is because I wish to do some basic validation and set a parent-child relationship.

Is there anyway using nHibernate to call an explicit method like 'Add'\'AddRange' to add a property to collection that is exposed by a getter method?


Cheers

Ollie


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 6:26 am 
Regular
Regular

Joined: Wed Jan 25, 2006 1:11 am
Posts: 118
Location: Copenhagen, Denmark
If its a collection you can implement a custom collectiontype


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 6:50 am 
Newbie

Joined: Mon Mar 17, 2008 6:07 am
Posts: 5
It's probably best to give a simple example, I wwant to know if it is possible to persist\hydrate the property 'Chidlren' on the 'Foo' class using the following methods?

Code:
public class Foo
{
    public HashSet<Bar> Children { get; private set; }
   
    public Foo Add(Bar bar)
    {
        if (bar == null)
                throw new ArgumentNullException("Blah");
      
        bar.Parent = this;
        if (!Children.Add(bar))
                throw new Exception("Duplicate");
        return this;
    }
   
    public Foo AddRange(List<Bar> bars)
    {
       if (bars == null)
                throw new ArgumentNullException("Blah");
      
       foreach(Bar bar in bars)
       {      
                bar.Parent = this;
                if (!Children.Add(bar))
                        throw new Exception("Duplicate");
       }
       
       return this;
    }   
}

public class Bar
{
       public string Prop1 { get; set; }
       public string Prop2 { get; set; }
   
       public Foo Parent { get; set; }
}



Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 7:03 am 
Regular
Regular

Joined: Wed Jan 25, 2006 1:11 am
Posts: 118
Location: Copenhagen, Denmark
Jeg this would work. nHibernate has no problem with accesing a private setter when hydrating the objekt. So know problem there your property will be published with its values. And when persisting the getter will be used.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 7:10 am 
Newbie

Joined: Mon Mar 17, 2008 6:07 am
Posts: 5
jta wrote:
Jeg this would work. nHibernate has no problem with accesing a private setter when hydrating the objekt. So know problem there your property will be published with its values. And when persisting the getter will be used.


Thanks for the response, I know that nHibernate can access the private variable to 'set' the property, but this would miss some of the business logic I wish to apply to each member of the collection when it is added.

Cheers

Ollie


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 7:36 am 
Regular
Regular

Joined: Wed Jan 25, 2006 1:11 am
Posts: 118
Location: Copenhagen, Denmark
But when i assume your database is consistent, so that items can be added directly to the property and when using the object manually you use the methods?

A problem is that in your example the collection can be added directly so it should prbaply be returned read-only


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 8:29 am 
Newbie

Joined: Mon Mar 17, 2008 6:07 am
Posts: 5
I can see from another fourm post that one can create bi-directional mappings - http://forum.hibernate.org/viewtopic.php?t=984636&highlight=parent+reference

This does make me wonder why bi-directional mapping are percieved as a bad idea?


Cheers

Ollie


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 8:56 am 
Regular
Regular

Joined: Wed Jan 25, 2006 1:11 am
Posts: 118
Location: Copenhagen, Denmark
Im not quite sure i follow this in the context of your original question. But i would argue bidirectional mappings removes flexibility to have properties in the relation itself


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 17, 2008 1:31 pm 
Newbie

Joined: Tue May 01, 2007 10:20 am
Posts: 9
oriches wrote:

Thanks for the response, I know that nHibernate can access the private variable to 'set' the property, but this would miss some of the business logic I wish to apply to each member of the collection when it is added.

Cheers

Ollie


I think the idea is that NHibernate assumes that when it's hydrating an object, that it's just bring back into memory what was once in memory some time ago and then persisted. So, if you have the following lifecycle..


1.) New object is created.
2.) Entity is added to collection via the Add method, which includes validation. Let's say that all checks in the Add method are OK, thus the Bar object is successfully added to the Children collection.
3.) Save() is called, persisting the entity to the DB.
4.) You close your program and make yourself a sandwich.
5.) You open your program, calling Load<Foo>(id)


Since the DB should only have entities that already did pass the validation in Add, it's redundant to check them again in AddRange. If the Bar entity you passed duing your pre-lunch session didn't pass the validation in Add, it would never have been persisted.

As jta explained, by not making your set publicly available, and instead forcing the user of the class to use your methods with the validation in them, you should be able to safely say that every entity in the collection passed the validation.

Now, there may be exceptions, two I can think of are...

1.) Your DB is being shared with another program that doesn't use your validation.
2.) You are creating a new version of your program that has tighter validation than a previous version, and entities in the DB might have been valid in a previous version, but no longer valid in the new version.

In either case, you may want to go with more of a passive validation scheme (using an IsValid() method on foo, for example). In the second case, you might also want to think of alter scripts for your database to bring entities that would become invalid into a valid state.

Hope that helps.


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