views:

300

answers:

1

Hello,

I have been using joinedsubclass inheritence mapping for a while and decided to switch to table-per-class because it allows more efficient subtype descrimination. However on making the change I now get the below exception.

Object with id: 1 was not of the specified subclass: MyModel.FooBase (Discriminator was: '2')

Abridged classes are as follows.

public abstract FooBase
{
    /* snip other properties */
    public virtual string Name { get;set; }
    public virtual IList<Child> Children { get; set; }
}

public class Bar : FooBase
{
    public virtual string NickName { get;set; }
}

public class Child
{
    public virtual FooBase Parent { get;set; }
}

And the mappings

public sealed class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        /*snip*/
        References(x => x.Parent).ColumnName("ParentId");
    }
}
public sealed class FooBaseMap : ClassMap<FooBase>
{
    public FooBaseMap()
    {
        /*snip*/
        HasMany(x => x. Children)
            .AsBag().Cascade
            .AllDeleteOrphan()
            .KeyColumnNames.Add("ParentId")
            .Inverse();

        DiscriminateSubClassesOnColumn<int>("FooType")
            .SubClass<Bar>(Types.Bar, m => m.Map(x => x.NickName))
    }
}

As it turns out this exception is normally seen on polymorphic collections not specifying a where attribute. Not the case here. I have played around with making the FooBase not abstract, this makes no difference. Didn't think changing mapping strategies would cause any problems other than having to have nullable columns on the subclasses.

The thing thats confusing is that I am not specifying a subclass as this is a polymorphic parent and I am only attempting to access the base properties in this case Name.

Many thanks,

+1  A: 

Ok I found the issue as always right after asking the question :(

Anyway it was the mapping using an Enum as the descriminator that was the issue.

DiscriminateSubClassesOnColumn<int>("FooType")
            .SubClass<Bar>(Types.Bar, m => m.Map(x => x.NickName))

Types is an enum I used to allow me to not forget the ints used as the descriminator (reason for ints is they are faster than strings in db lookups).

This issue implies you can use Enums directly as descriminators since 3892 so I tried.

DiscriminateSubClassesOnColumn<Types>("FooType")
            .SubClass<Bar>(Types.Bar, m => m.Map(x => x.NickName))

Didn't work so I tried

DiscriminateSubClassesOnColumn<Types>("FooType")
            .SubClass<Bar>("Bar", m => m.Map(x => x.NickName))

Also didn't work so I finally settled for the below which does work.

DiscriminateSubClassesOnColumn<int>("FooType")
            .SubClass<Bar>((int)Types.Bar, m => m.Map(x => x.NickName))
madcapnmckay