Thanks for the response. Let me say first that this is a dumb-down example, I'm not really modelling married people :)
The classes:
Code:
public abstract class Person
{
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
public class Man : Person
{
}
public class Woman : Person
{
}
public class MarriedMan : Man
{
private MarriedWoman _wife;
public MarriedWoman Wife
{
get { return _wife; }
set { _wife = value; }
}
}
public class MarriedWoman : Woman
{
private MarriedMan _husband;
public MarriedMan Husband
{
get { return _husband; }
set { _husband = value; }
}
}
The mapping:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" default-access="nosetter.camelcase-underscore" >
<class name="SancorSeguros.Inversiones.Person, SancorSeguros.Inversiones" table="Person" discriminator-value="-1">
<id name="Id" unsaved-value="0" access="nosetter.camelcase-underscore" >
<generator class="identity" />
</id>
<discriminator column="type" />
<property name="Name" />
<subclass name="SancorSeguros.Inversiones.Man, SancorSeguros.Inversiones" discriminator-value="M">
<subclass name="SancorSeguros.Inversiones.MarriedMan, SancorSeguros.Inversiones" discriminator-value="MM">
<many-to-one name="Wife" column="spouseID" />
</subclass>
</subclass>
<subclass name="SancorSeguros.Inversiones.Woman, SancorSeguros.Inversiones" discriminator-value="W">
<subclass name="SancorSeguros.Inversiones.MarriedWoman, SancorSeguros.Inversiones" discriminator-value="WW">
<many-to-one name="Husband" column="spouseID" />
</subclass>
</subclass>
</class>
</hibernate-mapping>
The table contains the data specified above.
To make it fail:
Code:
Person person = (Person)sess.Load(typeof(Person), 3);
The log:
Code:
2005-12-27 15:29:03,078 [5808] INFO NHibernate.Loader.Loader [(null)] <(null)> - SELECT person0_.Id as Id3_, person0_.type as type3_, person0_.Name as Name3_, person0_.spouseID as spouseID3_, marriedwom1_.Id as Id0_, marriedwom1_.spouseID as spouseID0_, marriedwom1_.Name as Name0_, marriedman2_.Id as Id1_, marriedman2_.spouseID as spouseID1_, marriedman2_.Name as Name1_, marriedman3_.Id as Id2_, marriedman3_.spouseID as spouseID2_, marriedman3_.Name as Name2_ FROM Person person0_ left outer join Person marriedwom1_ on person0_.spouseID=marriedwom1_.Id left outer join Person marriedman2_ on marriedwom1_.spouseID=marriedman2_.Id left outer join Person marriedman3_ on person0_.spouseID=marriedman3_.Id WHERE person0_.Id=@p0
2005-12-27 15:29:03,234 [5808] WARN NHibernate.Util.ADOExceptionReporter [(null)] <(null)> - NHibernate.WrongClassException: Object with id: 4 was not of the specified sublcass: SancorSeguros.Inversiones.MarriedMan (loading object was of wrong class)
at NHibernate.Loader.Loader.InstanceAlreadyLoaded(IDataReader rs, Int32 i, ILoadable persister, String suffix, Key key, Object obj, LockMode lockMode, ISessionImplementor session)
at NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, String[] suffixes, Key[] keys, Object optionalObject, Key optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session)
at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, IList hydratedObjects, Object optionalObject, Object optionalId, Key[] keys, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Object optionalObject, Object optionalId, Object[] optionalCollectionKeys, Boolean returnProxies)
2005-12-27 15:29:03,250 [5808] ERROR NHibernate.Util.ADOExceptionReporter [(null)] <(null)> - Object with id: 4 was not of the specified sublcass: SancorSeguros.Inversiones.MarriedMan (loading object was of wrong class)
If I ask for the exact type, not the superclass, it works ok (but it is not really an option):
Code:
Person person = (Person)sess.Load(typeof(MarriedMan), 3);
Also, asking for ID #4 works ok:
Code:
Person person = (Person)sess.Load(typeof(Person), 4);
This is .Net 2.0, MS SQL Server 2000
I can see in the SELECT that it goes like a circular reference, joining the person table four times.
BTW, the data was added without FK checks, I wonder how will I make the double reference work...