0

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?

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Dominic Jordan
  • 65
  • 1
  • 12
  • The exception seems pretty clear. What _specifically_ are you having trouble figuring out? If you really want help, you should post a better code example. See http://stackoverflow.com/help/mcve – Peter Duniho Nov 05 '14 at 20:29
  • Thanks for the reply! Im sorry, I have edited the question. I dont see how I should do the getter better. I hope you do? – Dominic Jordan Nov 05 '14 at 21:11

1 Answers1

0

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 the JobLog is not Log)

So, just assure that JobLog is subclass of Log... all will start to work

public class JobLog : Log

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335