Hi,
I was working on the following scenario and ran into a 'stackoverflow' exception.
( I am using nHibernate 2.1, oracle 11, c# 3.5)
- I have to persist 2 classes with a many-to-many relation (say, class A has a list of elements of type B)
- The relation between those 2 classes is redundant (e.g. class A has owns data which contains all necessary information to populate that relation)
- each class has a natural unique key (hence populating that relation requires a database lookup using a DAO)
And I tried the following approach (which leads to the mentioned stackoverflow exception) :
class A {
// other fields of A are not shown.
public Data Data{
get { ... }
set {
CalculateRedundantData(value);
this.data= value;
}
}
public IList<B> RedunantData {
get ; private set;
}
private void CalculateRedundantData(Data data) {
IList<B> list = new List<B>();
foreach(var key in data.UniqueKeysOfB) {
B b = repositoryOfB.LoadOrCreate(key); // this will do a database lookup and create a new instance of B when no row was returned.
list.Add(b);
}
RedunantData = list ;
}
}
Here the client code:
A a = LoadOrCreate(naturalKeyOfA) ;
a.Data = somedata ;
session.Save(a); // stackoverflow. CalculateRedundantData() is called over and over (due to a DeepCopy in nHibernate)
I have the following questions, maybe someone can help:
When I understand NHibernate correctly getters and setters are not the places where to put logic. They should only set and return the backing fields (they might contain validation logic though). Am I completely wrong with adding that kind of logic in a setter?
Is this a weakness of nHibernate because it only persists properties and not fields?
Do you know some smart way of solving this problem (maintaining redundant data) ?
I really don't like the idea of giving the class A a DAO for accessing class B, because I would rely on 'someone' injecting a valid DAO before the setter is called. Is there any best practice regarding 'injected' DAO's?