NHibernate: Persisting subclassed entity to main table (table per class strategy issue)

115 Views Asked by At

It is not a question but just for future... (spent many time to figure out)

public class A
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
}

public class B : A
{
    public string Lastname { get; set; }
}

Mappings (Fluent NHibernate):

public class AMap : ClassMap<A>
{
    Table("a");
    Id(x => x.Id).GeneratedBy.Native();
    Map(x => x.Name);
    Map(x => x.Type);

    DiscriminateSubClassesOnColumn<string>("Type")
            .AlwaysSelectWithValue();
}

public class BMap : ClassMap<B>
{
   DiscriminatorValue("BType");
   Extends<A>();
   Map(x => x.Lastname);
}

Persisting BMap object leads to Exception:

Exception:

Error dehydrating property value for A.Lastname

Inner Exception:

Invalid index 1 for this SqlParameterCollection with Count=1

This unobvious exceptions tell that some mapping missconfiguration occured. Actually "select" queries work pretty fine. But "insert into" (ISession.SaveOrUpdate) causes mentioned errors.

FIX:

In AMap class you don't need that line:

Map(x => x.Type);

After removing this persister works fine

1

There are 1 best solutions below

0
On

type does not need to be in the class nor mapped as property, it is purly implementation detail in the database to discriminate the types. Instead of Extends SubclassMap is more appropriate:

public class AMap : ClassMap<A>
{
    Table("A");
    Id(x => x.Id).GeneratedBy.Native();
    Map(x => x.Name);

    DiscriminateSubClassesOnColumn<string>("Type", "AType")
            .AlwaysSelectWithValue();
}

public class BMap : SubclassMap<B>
{
   DiscriminatorValue("BType");
   Map(x => x.Lastname);
}