Question

Assuming I run the following code:

var placementCriteria = DetachedCriteria.For<ResidentialPlacementClientService>();
placementCriteria.Add(Restrictions.Le("StartDate", effectiveDate));
placementCriteria.Add(Restrictions.Ge("EndDate", effectiveDate));
placementCriteria.SetFetchMode("CaseClient.CaseFile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.Incomes", FetchMode.Eager); 
placementCriteria.SetFetchMode("CaseClient.ClientProfile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.ClientProfile.Person", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService.Vendor", FetchMode.Eager);

using (var session = OpenSession())
{
    using (var tx = session.BeginTransaction())
    {
        residentialPlacements = placementCriteria.GetExecutableCriteria(session).List<ResidentialPlacementClientService>();
    }
}

The "Incomes" property on my is populated correctly.

Now when I add criteria on incomes, the property is no longer being fetched eagerly.

var placementCriteria = DetachedCriteria.For<ResidentialPlacementClientService>();
placementCriteria.Add(Restrictions.Le("StartDate", effectiveDate));
placementCriteria.Add(Restrictions.Ge("EndDate", effectiveDate));
placementCriteria.SetFetchMode("CaseClient.CaseFile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.Incomes", FetchMode.Eager); 
placementCriteria.SetFetchMode("CaseClient.ClientProfile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.ClientProfile.Person", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService.Vendor", FetchMode.Eager);


var caseClientCriteria = placementCriteria.CreateCriteria("CaseClient", JoinType.InnerJoin);

var incomesCriteria = caseClientCriteria.CreateCriteria("Incomes", JoinType.InnerJoin);
incomesCriteria.Add(Restrictions.Le("StartDate", effectiveDate));

incomesCriteria.Add(Restrictions.Or(Restrictions.Ge("EndDate", effectiveDate),
                                    Restrictions.IsNull("EndDate")));

incomesCriteria.Add(Restrictions.Eq("IncomeType", incomeType));

using (var session = OpenSession())
{
    using (var tx = session.BeginTransaction())
    {
        residentialPlacements = placementCriteria.GetExecutableCriteria(session).List<ResidentialPlacementClientService>();
    }
}

Why does NHibernate do this? How can I change my query/criteria so that the property is fetched eagerly?

Thanks.

Was it helpful?

Solution

if you have filters on an association then NH cant be sure that all entities of the association are returned to initialize the association collection. you can issue a Select for the ids and then fetch the entities with associations eagerly

...
placementCriteria.SetProjection(Projections.Id());

residentialPlacements = session.CreateCriteria<ResidentialPlacementClientService>()
    .Add(Subqueries.In("Id", placementCriteria))
    .SetFetchMode("CaseClient.CaseFile", FetchMode.Eager);
    .SetFetchMode("CaseClient.Incomes", FetchMode.Eager); 
    .SetFetchMode("CaseClient.ClientProfile", FetchMode.Eager);
    .SetFetchMode("CaseClient.ClientProfile.Person", FetchMode.Eager);
    .SetFetchMode("VendorService", FetchMode.Eager);
    .SetFetchMode("VendorService.Vendor", FetchMode.Eager);
    .List<ResidentialPlacementClientService>();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top