sqlnhibernatenhibernate-mappinghbm

How to map an NHibernate entity to a query


I've seen a number of examples of this, and as far as I can tell my HBM file follows the same pattern, but it's not working. First, the file:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
  <class name="ThinAir" mutable="false" lazy="true" >
    <id name="JobId">
      <generator class="native" />
    </id>
    <property name="UserLogin"/>
    <property name="UserEmail"/>
    <property name="DateProcessed"/>
    <loader query-ref="myquery"/>
  </class>
  <sql-query name="myquery">
    <return class="ThinAir">
      <return-property name="JobID" column="JobId"/>
      <return-property name="userLogin" column="UserLogin"/>
      <return-property name="DateProcessed" column="DateProcessed"/>
      <return-property name="userEmail" column="UserEmail"/>
    </return>
    <![CDATA[
    SELECT DISTINCT JobID,
    userLogin,
    DateProcessed,
    useremail
    FROM         dbo.someothertable
    ]]>
  </sql-query>
</hibernate-mapping>

"myquery" in-and-of-itself, works. That is to say, if I call

var x = session.GetNamedQuery("myquery").List();

I get a correct List of ThinAir objects.

But, when I try to get a list of ThinAirs like this:

var submissions = session.CreateCriteria<ThinAir>().List<ThinAir>();

I get

Test method testThinAir threw exception: NHibernate.Exceptions.GenericADOException: could not execute query [ SELECT this_.JobId as JobId16_0_, this_.UserLogin as UserLogin16_0_, this_.UserEmail as UserEmail16_0_, this_.DateProcessed as DateProc4_16_0_ FROM ThinAir this_ ]

My interpretation of this phenomenon is that NH is ignoring my <loader> tag and so trying to load the data from the underlying table, which by default it assumes to be named ThinAir because that's the name of the entity class, only there isn't any ThinAir table, hence the error message.

Is that interpretation correct? And in any case, what am I doing wrong and how can I do it right?

Thanks in advance.

Michael


Solution

  • One way how to achieve this, would be to move the mapping from a query into the subselect:

    <?xml version="1.0" encoding="utf-8"?>
    <hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
      <class name="ThinAir" mutable="false" lazy="true" >
    
      <subselect>
        <![CDATA[
        SELECT DISTINCT JobID,
        userLogin,
        DateProcessed,
        useremail
        FROM         dbo.someothertable
        ]]>
      </subselect>
    
      ... // rest of the mapping