I am having an odd error when using Fluent NHibernate. I have an entity object called Module that is my "aggregate root" if you will. I created and tested my mappings for the Module class and the various related classes and tried creating a Module with all of its fields filled out and saving it. This worked correctly.
My problem is when I try to retrieve the objects from the database. The Module object comes back just fine, however any of the collections it contains are all empty even though I see the objects in the database tables!! I could really use a hand on this one, I hope somone can help!
edit: added the code for BuildDeriveModule below.
Here is my test:
var dei1 = BuildDeriveModule();
var sessionSource = Injector.Resolve<ISessionSource>();
using (var session = sessionSource.CreateSession())
{
using (var transaction = session.BeginTransaction())
{
session.Save(dei1);
transaction.Commit();
}
}
Module item = null;
using (var session = sessionSource.CreateSession())
{
item = session
.CreateCriteria(typeof(Module))
.Add(Restrictions.Eq("ModuleId", dei1.ModuleId))
.UniqueResult<Module>();
Assert.Equal<Module>(dei1, item);
Assert.Equal<int>(4, item.Variables.Count);
}
My Module class looks like this: (Note: Entity comes from FluentNHibernate.Data.Entity)
public class Module : Entity, IEntity
{
public Module()
{
Variables = new HashedSet<ModuleVariable>();
}
public virtual string ModuleId
{
get;
set;
}
public virtual ISet<ModuleVariable> Variables
{
get;
set;
}
public virtual Variable StratumVariable
{
get;
set;
}
public virtual Stratum DefaultStratum
{
get;
set;
}
public virtual ISet<Stratum> OptionalStrata
{
get;
set;
}
public virtual DateTime LastUpdated
{
get;
set;
}
#region Override Methods
public override string ToString()
{
return this.ModuleId;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
var other = obj as Module;
if (other == null) return false;
if (other.ModuleId != this.ModuleId) return false;
return true;
}
public override int GetHashCode()
{
return ModuleId.GetHashCode();
}
#endregion
}
And my Mapping looks like this:
public class ModuleMap : ClassMap<Module>
{
public ModuleMap()
{
Id(x => x.Id);
Version(x => x.LastUpdated);
Map(x => x.ModuleId)
.Unique()
.Not.Nullable();
HasMany<ModuleVariable>(x => x.Variables)
.Inverse()
.Cascade.SaveUpdate();
References<Variable>(x => x.StratumVariable)
.Not.Nullable()
.Cascade.SaveUpdate();
References<Stratum>(x => x.DefaultStratum)
.Not.Nullable()
.Cascade.SaveUpdate();
HasMany<Stratum>(x => x.OptionalStrata)
.Inverse()
.Cascade.SaveUpdate();
}
}
BuildDeriveModule's code:
private Module BuildDeriveModule() { var pp01 = new Relation { RelationId = "PP01" };
var hh01 = new Relation
{
RelationId = "HH01"
};
var stdei1 = new Variable
{
VariableId = "STDEI1",
Relation = pp01
};
var frameId = new Variable
{
VariableId = "FRAME_ID",
Relation = pp01
};
var persno = new Variable
{
VariableId = "PERSNO",
Relation = pp01
};
var hp = new Driver
{
Name = "HP",
Phase = 1
};
hp.KeyVariables.Add(frameId);
hp.KeyVariables.Add(persno);
var r2p1 = new Variable
{
VariableId = "R2P1",
Relation = pp01
};
var age = new Variable
{
VariableId = "AGE",
Relation = pp01
};
var marst = new Variable
{
VariableId = "MARST",
Relation = pp01
};
var doctp = new Variable
{
VariableId = "DOCTP",
Relation = hh01
};
pp01.AddVariable(stdei1);
pp01.AddVariable(r2p1);
pp01.AddVariable(age);
pp01.AddVariable(marst);
hh01.AddVariable(doctp);
var defaultStratum = new Stratum
{
Number = -1,
Driver = hp
};
var dei1 = new Module
{
ModuleId = "DEI1",
StratumVariable = stdei1,
DefaultStratum = defaultStratum
};
var mv_r2p1 = new ModuleVariable
{
ModuleId = dei1,
VariableId = "R2P1",
UploadId = r2p1,
DownloadId = r2p1,
HasSubunits = true
};
var mv_age = new ModuleVariable
{
ModuleId = dei1,
VariableId = "AGE",
UploadId = age,
DownloadId = age,
HasSubunits = true
};
var mv_marst = new ModuleVariable
{
ModuleId = dei1,
VariableId = "MARST",
UploadId = marst,
DownloadId = marst,
HasSubunits = true
};
var mv_doctp = new ModuleVariable
{
ModuleId = dei1,
VariableId = "DOCTP",
UploadId = doctp,
DownloadId = doctp,
HasSubunits = false
};
dei1.AddVariable(mv_r2p1);
dei1.AddVariable(mv_age);
dei1.AddVariable(mv_marst);
dei1.AddVariable(mv_doctp);
return dei1;
}