I have a very simple master-child model:
WorkflowEscalationPolicy<--WorkflowEscalation.
The WorkflowEscalations are accessible from the WorkflowEscalationPolicy.Escalations
property.
I want to eagerly fetch the escalations when I get the WorkflowEscalationPolicy
items.
I have a method that gets all escalation policies. I have tried using this:
IEnumerable<IWorkflowEscalationPolicy> results =
Session
.Query<WorkflowEscalationPolicy>()
.Fetch(x=>x.Escalations)
.Where(q=>q.ApplicationKey==applicationKey);
and this:
IEnumerable<IWorkflowEscalationPolicy> results =
Session
.CreateCriteria<WorkflowEscalationPolicy>()
.SetFetchMode("Escalations", FetchMode.Eager)
.List<WorkflowEscalationPolicy>();
to accomplish this, but neither work - in that the child Escalations collection remains empty. I know that there are WorkflowEscalations
in the database.
My mapping files:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="FB.SimpleWorkflow.NHibernate"
namespace="FB.SimpleWorkflow.NHibernate.Model" >
<class name="WorkflowEscalationPolicy" table="SW_WorkflowEscalationPolicy" >
<id name="Id">
<generator class="native" />
</id>
<property name="ApplicationKey" />
<property name="ActivityKey" />
<property name="InstanceKey" />
<property name="State" />
<property name="EscalateAfterSeconds" />
<property name="MaximumEscalationsPerTransition" />
<set name="Escalations" table="SW_WorkflowEscalation" cascade="all-delete-orphan" inverse="true">
<key column="WorkflowEscalationPolicyId" />
<one-to-many class="WorkflowEscalation" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="FB.SimpleWorkflow.NHibernate"
namespace="FB.SimpleWorkflow.NHibernate.Model" >
<class name="WorkflowEscalation" table="SW_WorkflowEscalation" >
<id name="Id">
<generator class="native" />
</id>
<property name="EscalatedTimeStamp" />
<property name="EscalatedByUserName" />
<property name="EscalatedOnHost" />
<many-to-one name="WorkflowEscalationPolicy" column="WorkflowEscalationPolicyID" />
<many-to-one name="WorkflowActivityInstanceTransition" column="WorkflowActivityInstanceTransitionId" />
</class>
</hibernate-mapping>
What is the difference between the two and what am I missing here? I thought that in the first instance NHibernate refers to the mapping files for loading strategies?
NHibernate is v3.1
Update: 6 June 2013
Further investigations thanks to @cremor ...
I've profiled the generated SQL that the query executes and I get:
SELECT this_.Id as Id4_1_,
this_.ApplicationKey as Applicat2_4_1_,
this_.ActivityKey as Activity3_4_1_,
this_.InstanceKey as Instance4_4_1_,
this_.State as State4_1_,
this_.EscalateAfterSeconds as Escalate6_4_1_,
this_.MaximumEscalationsPerTransition as MaximumE7_4_1_,
escalation2_.WorkflowEscalationPolicyID as Workflow5_3_,
escalation2_.Id as Id3_,
escalation2_.Id as Id2_0_,
escalation2_.EscalatedTimeStamp as Escalate2_2_0_,
escalation2_.EscalatedByUserName as Escalate3_2_0_,
escalation2_.EscalatedOnHost as Escalate4_2_0_,
escalation2_.WorkflowEscalationPolicyID as Workflow5_2_0_,
escalation2_.WorkflowActivityInstanceTransitionID as Workflow6_2_0_
FROM SW_WorkflowEscalationPolicy this_
left outer join SW_WorkflowEscalation escalation2_ on this_.Id=escalation2_.WorkflowEscalationPolicyID
Which is what I would expect.
This generates the correct SQL, with the single detail Escalation record to the right of the master EscalationPolicy record. Therefore, the database is fine, the T-SQL is fine and therefore there is a misunderstanding within the NHibernate somewhere.