Question

I have a Status property in one of my POCO's that acts as a discriminator (very similar to using an enum).

Here is part of the HBM that has the Status column.

<many-to-one class="Locate.Common.Domain.Statuses.Status, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Status">
  <column name="Status_id" not-null="true" />
</many-to-one>

And here is my HBM for the Status table.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Locate.Common.Domain.Statuses.Status, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Status`">
    <id access="nosetter.lowercase-underscore" name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Status_id" />
      <generator class="assigned" />
    </id>
    <discriminator type="String">
      <column name="Status_id" />
    </discriminator>
    <property access="nosetter.lowercase-underscore" name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" not-null="true" />
    </property>
    <property access="nosetter.camelcase-underscore" name="IsUserSelectable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="IsUserSelectable" not-null="true" />
    </property>
    <subclass name="Locate.Common.Domain.Statuses.CallbackStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="3" />
    <subclass name="Locate.Common.Domain.Statuses.EmergencyStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="5" />
    <subclass name="Locate.Common.Domain.Statuses.FirstCheckerStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1" />
    <subclass name="Locate.Common.Domain.Statuses.PleaseAdviseStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="4" />
    <subclass name="Locate.Common.Domain.Statuses.SecondCheckerStatus, Locate.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="2" />
  </class>
</hibernate-mapping>

Lastly, here is my QueryOver.

var locates =
    session.QueryOver(() => locateAlias)
    .SelectList(x => x
        .Select(xx => xx.WorkToBeginDateTime).WithAlias(() => sentTo.DueDate)
        .Select(xx => xx.SendTo).WithAlias(() => sentTo.SentTo)
        .Select(xx => xx.TicketNo).WithAlias(() => sentTo.TicketNo)
        .Select(xx => xx.Status).WithAlias(() => sentTo.Status)
    )
    .JoinAlias(() => locateAlias.Status, () => statusAlias)
    .Where(() => locateAlias.IsComplete == false)
    .TransformUsing(Transformers.AliasToBean<SentToDto>()).List<SentToDto>();

This query runs without error however the Status property isn't getting initialized properly. When I go to use the Status value I receive this exception.

Initializing[Locate.Common.Domain.Statuses.Status#2]-Could not initialize proxy - no Session.

Looking at the NHibernate Profiler I can see that it is in fact selecting the proper Status_id.

What's wrong with me HBM or query?

Note that I am successfully able to query for all statuses and receive a list of all status discriminator objects. I can also see that the proxy object generated contains the correct values of the Status object so NHibernate is properly returning the correct values.

Was it helpful?

Solution

your Query doesnt Eeger-fetch the Status property and later, when you access Status the session, with which you loaded the locates is already closed. So instead of .JoinAlias(() => locateAlias.Status, () => statusAlias) use .Fetch(locate => locate.Status).Eager

Edit: i verified, its because of the Selects that Status is not eagerly fetched. Its only eager fetching if a locate-object is returned. you could do:

var locates =
    session.QueryOver(() => locateAlias)
    .Where(() => locateAlias.IsComplete == false)
    .Fetch(locate => locate.Status).Eager
    .ToEnumerable()
    .Select(locate => new SentToDto
    {
        DueDate = locate.WorkToBeginDateTime,
        SendTo = locate.SendTo,
        TicketNo = locate.TicketNo,
        Status = locate.Status,
    }.ToList();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top