1

Say for example, I have the following:

public interface IPet
{
    long? Id { get; set; }
    string Name { get; set; }
}

public class Cat : IPet
{
    public virtual long? Id { get; set; }
    public virtual string Name { get; set; }
}

public class Dog : IPet
{
    public virtual long? Id { get; set; }
    public virtual string Name { get; set; }
}

And the following mappings:

<class name="Cat" table="`Cat`" >
  <id name="Id" type="long">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
</class>

<class name="Dog" table="`Dog`" >
  <id name="Id" type="long">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
</class>

Now when I do the following:

IList<IPet> pets = session.CreateCriteria<IPet>().List<IPet>();

Because of implicit polymorphism, a nice feature, it returns all cats and dogs. Now consider this:

public class PetShop
{
    public long? Id { get; set; }
    public List<IPet> Pets { get; set; }
}

<class name="PetShop" table="`PetShop`" >
  <id name="Id" type="long">
    <generator class="identity"/>
  </id>
  <property name="Name"/>
  <bag name="Pets"  cascade="all">
    <key column="PetShopId"/>
    <one-to-many class="IPet"/>
  </bag>
</class>

I was hoping this would mean the collection of pets would use implicit polymorphism to fill the collection, but instead I get the error 'Association references unmapped class: IntefaceCollectionExample.Domain.Entities.IPet'. I could create a mapping and table for IPet witch only included the Id, but this feels unintuitive. I could use union-subclass but would then lose the option to use generator class="identity". I could use many-to-any but I feel this would be rather clumsy in this case.

Is there something I'm missing? Is there a way to create a mapping for an interface for IPet but not need a table, and then specify that Cat and Dog implement this. Or is there any better way of acheiving this than the methods I have listed above?

Paul T Davies
  • 2,527
  • 2
  • 22
  • 39

1 Answers1

1

Implicit polymorphism is not supported for one-to-many scenarios

You can either use an explicit inheritance strategy (i.e. the whole hierarchy must be mapped, starting with the interface), or create a table for the collection and map as many-to-any.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
  • When you say the whole heirachy must be mapped, are you advocating having a table for IPet like I mentioned? It does seem that what I wanted to do just can't be done. That's a shame - that would be a nice feature. – Paul T Davies Jul 25 '11 at 07:57
  • @PaulTDavies: you can avoid having a table for the interface by using the [Table per concrete class](http://www.nhforge.org/doc/nh/en/index.html#inheritance-tableperconcrete) strategy. But it's not necessarily better. – Diego Mijelshon Jul 25 '11 at 11:30