Efficently loading deep object graphs

Here is an interesting approach to get deep object graphs effectively.  This will ensure that you will get all the relevant collections without having to lazy load them and without a huge cartesian product. Especially useful if you want to load a collection of items with the associated deep object graph.

public Policy GetPolicyEagerly(int policyId)
{
	IList list = ActiveRecordUnitOfWorkFactory.CurrentSession.CreateMultiQuery()
		.Add(@"from Policy policy left join fetch policy.PolicyLeadAssociations
where policy.Id = :policyId") .Add(@"from Policy policy left join fetch policy.PolicyEmployeeAssociations
where policy.Id = :policyId") .Add(@"from Policy policy left join fetch policy.PolicyManagerAssociations
where policy.Id = :policyId
") .Add(@"from Policy policy left join fetch policy.PolicyDepartmentAssociations
where policy.Id = :policyId
") .Add(@"from Policy policy left join fetch policy.PolicyCustomerAssociations
where policy.Id = :policyId
") .SetEntity("policy", Policy) .List(); IList firstResultList = (IList) list[0]; if(firstResultList.Count==0) return null; return = (Policy) firstResultList [0]; }

The domain above is a fake one, by the way, don't try to make any sense of it.

Print | posted on Wednesday, June 20, 2007 8:05 PM

Feedback


# re: Efficently loading deep object graphs 6/21/2007 12:01 AM Frans Bouma

You mean... there are o/r mappers out there which fetch graphs using cartesian products? :X

Ugh...


Gravatar

# re: Efficently loading deep object graphs 6/21/2007 12:07 AM Ayende Rahien

I mean, that is one option that you have, yes.


 re: Efficently loading deep object graphs 6/21/2007 11:53 AM Florent Dugue

Sorry for my ignorance, but what's the difference with adding "SetFetchMode" ?

IList list = Session.CreateCriteria(typeof (Policy ))
.SetFetchMode("PolicyLeadAssociations", FetchMode.Join)
.SetFetchMode("PolicyEmployeeAssociations", FetchMode.Join)
.SetFetchMode("PolicyManagerAssociations", FetchMode.Join)
.SetFetchMode("PolicyDepartmentAssociations", FetchMode.Join)
.SetFetchMode("PolicyCustomerAssociations", FetchMode.Join)
.List();


Gravatar

# re: Efficently loading deep object graphs 6/21/2007 11:55 AM Ayende Rahien

This will return a single result set.
The problem with that is that if you try to load all of that in a single result set, you will have a big Cartesian product.
The approach above uses separate queries, but only a single round trip


Gravatar

 re: Efficently loading deep object graphs 6/21/2007 11:56 AM Sven

Florent, I'm guessing what you wrote would cause the huge cartesian product Ayende mentioned.


Gravatar

 re: Efficently loading deep object graphs 6/21/2007 11:57 AM Sven

Damn, he's just too quick, isn't he ? :-)


 re: Efficently loading deep object graphs 6/21/2007 12:08 PM Florent Dugue

Ok, if I understand well, you mean it's faster to do 5 requests with only one join between two tables in each request instead of one big request between the 6 tables ?

BTW, I forgot the .Add(new EqExpression("Id", policyId)) between CreateCritera and the first SetFetchMode for removing the Cartesian product.

@Sven : yeah, damn fast ! ;)


Gravatar

# re: Efficently loading deep object graphs 6/21/2007 12:57 PM Ayende Rahien

@ Florent,
Yes, that would be faster, but the key part here is that it is 5 request, but a SINGLE round trip


Gravatar

# re: Efficently loading deep object graphs 6/30/2007 7:10 PM Jim Geurts

I may be mistaken, but shouldn't the line:

.SetEntity("policy", Policy)

be

.SetInt32("policyId", policyId)


Gravatar

# re: Efficently loading deep object graphs 6/30/2007 7:50 PM Ayende Rahien

Yes, it should be


 re: Efficently loading deep object graphs 7/5/2007 11:40 PM Allen

I'm wondering what is the Hibernate equivalent syntax for achieving this since there's no CreateMultiQuery() function?


Gravatar

# re: Efficently loading deep object graphs 7/5/2007 11:59 PM Ayende Rahien

Allen,
That is something that I added to NHibernate, Hibernate has no equivalent that I know of

Comments have been closed on this topic.