I have a huge problem! I keep getting an exception when mapping an abstract class with multiple union-subclasses in nhibernate. When I use only one union-subclass I dont get any error and everything works fine. When I use more subclasses this error occures:
[TargetException: Object does not match target type.] System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) +10909543 System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +115 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +54 System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) +61 System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index) +19 NHibernate.Properties.BasicGetter.Get(Object target) +99
[PropertyAccessException: Exception occurred getter of MedControlWeb.Models.Logs.Log.Code] NHibernate.Properties.BasicGetter.Get(Object target) +183 NHibernate.Engine.UnsavedValueFactory.GetUnsavedIdentifierValue(String unsavedValue, IGetter identifierGetter, IType identifierType, ConstructorInfo constructor) +160 NHibernate.Tuple.PropertyFactory.BuildIdentifierProperty(PersistentClass mappedEntity, IIdentifierGenerator generator) +200 NHibernate.Tuple.Entity.EntityMetamodel..ctor(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory) +775 NHibernate.Persister.Entity.AbstractEntityPersister..ctor(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory) +835 NHibernate.Persister.Entity.UnionSubclassEntityPersister..ctor(PersistentClass persistentClass, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping mapping) +220 NHibernate.Persister.PersisterFactory.CreateClassPersister(PersistentClass model, ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory, IMapping cfg) +369 NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners) +2199 NHibernate.Cfg.Configuration.BuildSessionFactory() +181
My hbm file:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MedControlWeb"
namespace="MedControlWeb.Models.Logs">
<class name="Log" abstract="true" lazy="false">
<id name="Code" column="code">
<generator class="hilo"/>
</id>
<property name="Description" column="description"/>
<property name="User" column="user"/>
<property name="Timestamp" column="timestamp"/>
<property name="Action" column="action"/>
<union-subclass name="SettingsLog" table="settings_log" lazy="false">
</union-subclass>
<union-subclass name="JobLog" table="job_log" lazy="false">
</union-subclass>
</class>
</hibernate-mapping>
My abstract super class:
public class Log
{
public int Code { get; set; }
public DateTime Timestamp { get; set; }
public MedControlWeb.Enums.Action Action { get; set; }
public string Description { get; set; }
public int User { get; set; }
}
One of the subclasses:
public class SettingsLog : Log
{
}
Where am I going wrong?
Edit: What can I do to solve this error? I dont see how I can fix it since I have proper get methods?
Believe or not, solution here is really surprisingly simple. This is the mapping:
<class name="Log" ...
...
<union-subclass name="SettingsLog" table="settings_log" lazy="false">
</union-subclass>
<union-subclass name="JobLog" table="job_log" lazy="false">
</union-subclass>
This is above snippet of the class SettingsLog
:
public class SettingsLog : Log // this is it, SettingsLog is also a Log
{...}
which is working and for sure, the SettingsLog
- is also Log
. The issue reported, does not come from the fact:
... getting an exception when mapping an abstract class with multiple union-subclasses...
But with a fact, that the other mapped union-subclass
is not a Log
:
public class JobLog // this is NOT a Log..
{...}
That's why we can see:
Exception: Object does not match target type
(well - yes, because theJobLog
is notLog
)
So, just assure that JobLog
is subclass of Log
... all will start to work
public class JobLog : Log