Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate Table Per Class loading - wrong type

I have a mapping issue with the table-per-class hierarchy in Fluent/NHibernate. When retrieving the records from the database, I keep getting an error (the Wrong type exception)

Object with id: 2445763 was not of the specified subclass: ClassA (loading object was of wrong class [ClassB]) (record 2445763 does have the value "2" in the Type column)

In my domain, I have EntryBase, ClassA and ClassB. The classes are defined as

public abstract class EntryBase 
{
    public virtual int Id {get;set;}
    public virtual string CommonProperty1 {get;set;}
    *... (lots of other common properties)*
    public virtual string CommonPropertyN {get;set;}
}

public class ClassA : EntryBase 
{
    public virutal string ClassAOnlyProperty {get;set;}
}

public class ClassB : EntryBase 
{
    public virutal string ClassBOnlyProperty {get;set;}
    public virutal int ClassBOnlyOtherProperty {get;set;}
}

The mappings are:

public class EntryBaseMap : ClassMap<EntryBase>
{
    public EntryBaseMap()
    {
        Table("MySingleTable");
        Id(x => x.Id, "RecordId").GeneratedBy.Identity();
        Map(x => x.CommonProperty1, "Field1Name");
        ...
        Map(x => x.CommonPropertyN, "FieldNName");
        DiscriminateSubClassesOnColumn<string>("Type");
    }
}

public class ClassAMap : SubclassMap<ClassA>
{   
    public ClassAMap()
    {
        DiscriminatorValue("1");
        Map(x => x.ClassAOnlyProperty);
    }
}

public class ClassBMap : SubclassMap<ClassB>
{   
    public ClassBMap()
    {
        DiscriminatorValue("2");
        Map(x => x.ClassBOnlyProperty);
        Map(x => x.ClassBOnlyOtherProperty);
    }
}

Any idea what might be amiss? I've correctly been able to store records of Class B, but when I retrieve them, it's attempting to load them as Class A. Is it a mapping problem?

like image 695
reallyJim Avatar asked Oct 10 '11 13:10

reallyJim


1 Answers

As discussed in the comments, if you have collection properties meant to represent a single subclass, you need to add a where clause in the mapping:

.Where("Type = '1'")

Type is your discriminator column and 1 is the discriminator value that matches the type you're trying to load.

like image 124
Jay Avatar answered Sep 30 '22 14:09

Jay