views:

331

answers:

1

I have an interface IUserLocation and a concrete type UserLocation.

When I use ICriteria, specifying the interface IUserLocation, I want NHibernate to instantiate a collection of the concrete UserLocation type.

I have created an HBM mapping file using the table per concrete type strategy (shown below). However, when I query NHibernate using ICriteria I get:

NHibernate cannot instantiate abstract class or interface MyNamespace.IUserLocation

Can anyone see why this is? (source code for the relevant bit of NHibernate here (I think))

My ICriteria:

var filter = DetachedCriteria.For<IUserLocation>()
                             .Add(Restrictions.Eq("UserId", userId));

return filter.GetExecutableCriteria(UoW.Session)
             .List<IUserLocation>();

My mapping file:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="MyNamespace.IUserLocation,MyAssembly" abstract="true" table="IUserLocations">
    <composite-id>
      <key-property name="UserId" column="UserId" type="System.Guid"></key-property>
      <key-many-to-one name="Location" column="LocationId" class="MyNamespace.ILocation,MyAssembly"></key-many-to-one>
    </composite-id>
    <union-subclass table="UserLocations" name="MyNamespace2.UserLocation,MyAssembly2">
      <property name="IsAdmin" />
    </union-subclass>    
  </class>  
</hibernate-mapping>
+1  A: 

From the documentation it looks like your mapping file should do it to me. I've never tried table per concrete class though. And I notice the examples in the NHibernate documentation for it don't use interfaces for the base class. Perhaps it's not supported?

I have used Table per concrete class, using implicit polymorphism before with a separate mapping for each subclass.

<class name="MyNamespace.UserLocation,MyAssembly" table="UserLocations">
    ...
</class>
David Hogue
Thanks David. It occurs to me that I may be barking up the wrong tree, as I am trying to use NHibernate a bit like an IOC container here, instantiating a concrete type where I only supply an interface. If NHibernate supports this, I think it'd be pretty useful.Due to limitations of the solution I am working with it is impractical to modify the interface to be an abstract base class. As a temporary hack I am using the IOC container to resolve the concrete type of the interface for supply to the ICriteria.
Ben Aston
I started looking at this again and I noticed that if the mapping file uses UserLocation instead of IUserLocation and the union-subclass is removed you can still reference it as IUserLocation in the criteria and get back an IList<IUserLocation>.
David Hogue