Registering mappings in mapping by code does not process classes accordingly to inheritance path
Description
I have this structure (pseudo code):
public abstract class BaseClass // mapping: public class BaseClassMapping : ClassMapping<BaseClass>
public class aClass : BaseClass // mapping: public class aClassMapping : SubclassMapping<aClass> public abstract subBaseclass : BaseClass // mapping: public class subBaseclassMapping : SubclassMapping<subBaseclass>
public abstract bClass : subBaseclass // mapping: public class bClassMapping : SubclassMapping<bClass>
now if I register my mappings using GetTypes I get an exception telling me I am trying to extend the unmapped class subBaseclass with my mapping of it's derived class bClass. code: mapper.AddMappings(typeof(MyAssembly).Assembly.GetTypes()); exception: NHibernate.MappingException : Cannot extend unmapped class: MyDomain.subBaseclass problem: the problem is that it tries to add the mapping of bClass while it's baseclass hasn't been added yet. workaround: add the mappings that have order-issues by hand and then add the rest. thus: mapper.AddMapping<subBaseclassMapping>(); mapper.AddMapping<bClassMapping>(); mapper.AddMappings(typeof(MyAssembly).Assembly.GetTypes());
We're still experiencing this bug in 4.1. OrderBy with TypeHierarchyComparer at its current form is not enough to guarantee the proper type order. It's very well explained in this comment:
Be very careful with the last return 0 ... the comparison algorithm doesn't always compare the types that you think directly, but instead the comparison can be made through a 3rd type. Supose that you have types A, B, C and C inherits from B, in this case the comparer will do: A==B ... A==C ... then it assumes that B==C and you end up with the wrong order - the Compare method never gets called for types B and C!
I have this structure (pseudo code):
public abstract class BaseClass // mapping: public class BaseClassMapping : ClassMapping<BaseClass>
public class aClass : BaseClass // mapping: public class aClassMapping : SubclassMapping<aClass>
public abstract subBaseclass : BaseClass // mapping: public class subBaseclassMapping : SubclassMapping<subBaseclass>
public abstract bClass : subBaseclass // mapping: public class bClassMapping : SubclassMapping<bClass>
now if I register my mappings using GetTypes I get an exception telling me I am trying to extend the unmapped class subBaseclass with my mapping of it's derived class bClass.
code: mapper.AddMappings(typeof(MyAssembly).Assembly.GetTypes());
exception: NHibernate.MappingException : Cannot extend unmapped class: MyDomain.subBaseclass
problem: the problem is that it tries to add the mapping of bClass while it's baseclass hasn't been added yet.
workaround: add the mappings that have order-issues by hand and then add the rest. thus:
mapper.AddMapping<subBaseclassMapping>();
mapper.AddMapping<bClassMapping>();
mapper.AddMappings(typeof(MyAssembly).Assembly.GetTypes());