title: NHibernate - How to map to a class that has no table (for custom sql queries)
body: <blockquote>
    <p>Update - Edited config for readability
    in SO</p>
  </blockquote>
  
  <p>Hi,</p>
  
  <p>I've been learning NHibernate for a day or two but getting stuck on one point.</p>
  
  <p>I need to be able to execute custom stored procedures and use NHibernate to map them back to domain classes.</p>
  
  <p>I have this working for the scenario where the custom query maps back to a object that maps to a database table, as shown by many a nhibernate example (See first  section below).</p>
  
  <p>However in the config for the second  section below, the query pulls only 2 columns from the target table. For this reason, I have created a custom object so that NHibernate has something to map the return values to. The custom object properties have the same name as the return columns from the custom procedure.</p>
  
  <p>When I run my tests I get an exception like:</p>
  
  <blockquote>
    <p>NHibernate.MappingException: No
    persister for:
    Proj.DataEntityTracker.Domain.Entities.CustomObject</p>
  </blockquote>
  
  <p>So I guess the mapping under sql-query section is not enough for NHibernate to map the return values to the object properties.</p>
  
  <p>So my question is - how do I set up a mapping for which there is no equivalent table in the database such that I can map the results of a stored procedure to that object?</p>
  
  <pre>
  
  &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
  &lt;hibernate-mapping xmlns=&quot;urn:nhibernate-mapping-2.2&quot;
                     assembly=&quot;Proj.DataEntityTracker.Domain&quot;
                     namespace=&quot;Proj.DataEntityTracker.Domain.Entities&quot;&gt;
  
    &lt;class name=&quot;TrackedEntityProperty&quot; table=&quot;TrackedEntityProperties&quot;&gt;
      &lt;id name=&quot;ID&quot; type=&quot;Int32&quot; unsaved-value=&quot;0&quot;&gt;
        &lt;generator class=&quot;native&quot;&gt;&lt;/generator&gt;
      &lt;/id&gt;
      &lt;property name=&quot;TrackedEntityID&quot; /&gt;
      &lt;property name=&quot;Name&quot; /&gt;
      &lt;property name=&quot;CreatedDate&quot; /&gt;
      &lt;property name=&quot;ChangedDate&quot; /&gt;
      &lt;property name=&quot;DataType&quot; /&gt;
      &lt;property name=&quot;CurrentValue&quot; /&gt;
      &lt;property name=&quot;RequestPropertyValueQuestion&quot; /&gt;
      &lt;property name=&quot;NullResponseIsAcceptable&quot; /&gt;
      &lt;property name=&quot;Duplication&quot; /&gt;
      &lt;property name=&quot;Frequency&quot; /&gt;
      &lt;property name=&quot;IsActive&quot; /&gt;
      &lt;property name=&quot;IsDeleted&quot; /&gt;
      &lt;property name=&quot;LastUpdateTaskGenerated&quot; /&gt;
      &lt;property name=&quot;LastUpdateTaskCompleted&quot; /&gt;
      &lt;property name=&quot;LastUpdateTaskCancelled&quot; /&gt;
    &lt;/class&gt;
  
    &lt;sql-query name=&quot;usp_GetTrackedEntityPropertiesDueForUpdate&quot; &gt;
      &lt;return alias=&quot;usp_GetTrackedEntityPropertiesDueForUpdate&quot; class=&quot;TrackedEntityProperty&quot;&gt;
  
        &lt;return-property name=&quot;ID&quot; column=&quot;ID&quot; /&gt;
        &lt;return-property name=&quot;TrackedEntityID&quot; column=&quot;TrackedEntityID&quot; /&gt;
        &lt;return-property name=&quot;Name&quot; column=&quot;Name&quot; /&gt;
        &lt;return-property name=&quot;CreatedDate&quot; column=&quot;CreatedDate&quot; /&gt;
        &lt;return-property name=&quot;ChangedDate&quot; column=&quot;ChangedDate&quot; /&gt;
        &lt;return-property name=&quot;DataType&quot; column=&quot;DataType&quot; /&gt;
        &lt;return-property name=&quot;CurrentValue&quot; column=&quot;CurrentValue&quot; /&gt;
        &lt;return-property name=&quot;RequestPropertyValueQuestion&quot; column=&quot;RequestPropertyValueQuestion&quot; /&gt;
        &lt;return-property name=&quot;NullResponseIsAcceptable&quot; column=&quot;NullResponseIsAcceptable&quot; /&gt;
        &lt;return-property name=&quot;Duplication&quot; column=&quot;Duplication&quot; /&gt;
        &lt;return-property name=&quot;Frequency&quot; column=&quot;Frequency&quot; /&gt;
        &lt;return-property name=&quot;IsActive&quot; column=&quot;IsActive&quot; /&gt;
        &lt;return-property name=&quot;IsDeleted&quot; column=&quot;IsDeleted&quot; /&gt;
        &lt;return-property name=&quot;LastUpdateTaskGenerated&quot; column=&quot;LastUpdateTaskGenerated&quot; /&gt;
        &lt;return-property name=&quot;LastUpdateTaskCompleted&quot; column=&quot;LastUpdateTaskCompleted&quot; /&gt;
        &lt;return-property name=&quot;LastUpdateTaskCancelled&quot; column=&quot;LastUpdateTaskCancelled&quot; /&gt;
  
      &lt;/return&gt;
  
      exec usp_GetTrackedEntityPropertiesDueForUpdate :TrackedEntityID
  
    &lt;/sql-query&gt;
  
    &lt;sql-query name=&quot;usp_SomeCustomSproc&quot;&gt;
      &lt;return alias=&quot;usp_SomeCustomSproc&quot; class=&quot;CustomObject&quot;&gt;
  
        &lt;return-property name=&quot;ID&quot; column=&quot;ID&quot; /&gt;
        &lt;return-property name=&quot;Name&quot; column=&quot;Name&quot; /&gt;
  
      &lt;/return&gt;
  
      exec usp_SomeCustomSproc :TrackedEntityID
  
    &lt;/sql-query&gt;
  
  &lt;/hibernate-mapping&gt;
  
  </pre>