I have a 3-leveled hierarchy of entities: Customer-Order-Line, which I would like to retrieve in entirety for a given customer, using ISession.Get(id). I have the following
If you need to keep your one-to-manys as bags, then you can issue 2 queries, each with only 1 level of hierarchy. eg something like this:
var temp = session.CreateCriteria( typeof( Order ) )
.SetFetchMode( "Lines", NHibernate.FetchMode.Eager )
.Add( Expression.Eq( "Customer.ID", id ) )
.List();
var customer = session.CreateCriteria( typeof( Customer ) )
.SetFetchMode( "Orders", NHibernate.FetchMode.Eager )
.Add( Expression.Eq( "ID", id ) )
.UniqueResult();
Lines get loaded into the NH cache in the first query, so they won't need lazy loading when later accessing eg customer.Orders[0].Lines[0].
@Tigraine: your query only returns Post with Comments. This brings All posts with all Comments (2 levels). What Ben asking is Customer to Order To LineItem (3 level). @Ben: to my knowledge nHibernate doesn't support eager loading upto 3 level yet. Hibernate does support it thou.
You're getting 4XOrder and 4XLines because the join with lines doubles the results . You can set a Transformer on the ICriteria like :
.SetResultTransformer(new DistinctRootEntityResultTransformer())
I was having the same problem. See this thread. I didn't get a solution but a hint from Fabio. Use Set instead of bag. And it worked.
So my suggestion is try to use set. You don't have to use Iesi collection use IDictonary and NH is happy
public override IEnumerable<Baseline> GetAll()
{
var baselines = Session.CreateQuery(@" from Baseline b
left join fetch b.BaselineMilestones bm
left join fetch bm.BaselineMilestonePrevious ")
.SetResultTransformer(Transformers.DistinctRootEntity)
.List<Baseline>();
return baselines;
}
I just read Ayende's Blogpost where he used the following Example:
session.CreateCriteria(typeof(Post))
.SetFetchMode("Comments", FetchMode.Eager)
.List();
In a Criteria Query to avoid Lazy Loading on one particular Query
Maybe that can help you.