3

I'm new to NHibernate, and am trying to map a domain model that has a bit of inheritence etc (see this question for full details on my model, starting a new question as this is a different error)

My base class has some abstract methods that each class beneath has to implement. This appears to be causing problems with NHibernate, even though I've implemented the class in my domain model, NHibernates proxy class seems to be having trouble.

One such method is SetRequired which is a void in my Question class and I've overriden it everywhere, but when I'm trying to test my mappings I'm getting this error:

PmqccFormIntegrationTests.TestJobVelocityQuestionPersists : FailedNHibernate.HibernateException : Creating a proxy instance failed
  ----> System.TypeLoadException : Method 'SetRequired' in type 'QuestionProxy' from assembly 'QuestionProxyAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
at NHibernate.ByteCode.LinFu.ProxyFactory.GetProxy(Object id, ISessionImplementor session)
at NHibernate.Tuple.Entity.AbstractEntityTuplizer.CreateProxy(Object id, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.CreateProxy(Object id, ISessionImplementor session)
at NHibernate.Event.Default.DefaultLoadEventListener.CreateProxyIfNecessary(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options, IPersistenceContext persistenceContext)
at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.Load(String entityName, Object id)
at NHibernate.Impl.SessionImpl.Load(Type entityClass, Object id)
at PmqccDomain.DataAccess.NHibernate.AbstractNHibernateDao`2.GetById(IdT id, Boolean shouldLock) in AbstractNHibernateDao.cs: line 31
at PMQCC_IntegrationTests.PmqccFormIntegrationTests.TestJobVelocityQuestionPersists() in PmqccFormIntegrationTests.cs: line 92
--TypeLoadException
at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateType()
at LinFu.DynamicProxy.ProxyFactory.CreateUncachedProxyType(Type[] baseInterfaces, Type baseType)
at LinFu.DynamicProxy.ProxyFactory.CreateProxyType(Type baseType, Type[] baseInterfaces)
at LinFu.DynamicProxy.ProxyFactory.CreateProxy(Type instanceType, IInterceptor interceptor, Type[] baseInterfaces)
at NHibernate.ByteCode.LinFu.ProxyFactory.GetProxy(Object id, ISessionImplementor session) 

I've tried setting 'abstract="true"' in my mapping files, and lazy="false" but I'm still getting the error. Thoughts?

EDIT: here is my current mapping

 <class name ="PmqccDomain.DomainObjects.Question,PmqccDomain" abstract="true" table="Questions">
    <id column="QuestionId" name="Id" type="Int32" unsaved-value="-1">
      <generator class="native"></generator>
    </id>
    <discriminator column="QuestionType" type="String" />
    <property name="Explanation"/>
    <many-to-one name="PmqccForm" class="PmqccDomain.DomainObjects.PmqccForm" column="PmqccFormId" />


    <!-- Subclass for Normal Question-->
    <subclass name="PmqccDomain.DomainObjects.NormalQuestion,PmqccDomain" abstract="true"  lazy="false">
      <property name="InputtedAnswer"/>

      <!-- Each Question Subclassed-->
      <subclass name="PmqccDomain.DomainObjects.AsConsQuestion,PmqccDomain" lazy="false" />
      <subclass name="PmqccDomain.DomainObjects.PiAlertQuestion,PmqccDomain" lazy="false">

        <many-to-one name="ResponsibleStaffMember" class="PmqccDomain.DomainObjects.StaffMember" column="ResponsibleStaffId" />

      </subclass>

    </subclass>

    <!-- Subclass for Job Velocity Question-->
    <subclass name="PmqccDomain.DomainObjects.JobVelocityQuestion,PmqccDomain" lazy="false">
      <property name="InputtedAnswer"/>

    </subclass>

  </class>

1 Answer 1

3

I believe the key is to declare such methods as: protected internal abstract as this will allow the proxies to inherit from them. You read read more about this here.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, this led me to my solution. I had it as protected internal abstract, but the problem is that as its internal, the DynamicProxy dll cannot access it. I made it public abstract and it works fine. It also shoudl work if you use the InternalsVisibleTo and set it to the dynamicProxy.dll
@RodH257 - ah yes, I remembered facing a similar problem awhile back, but obviously got the specifics wrong - the posting I linked to helped me to solve the problem as well.
I have the same problem. If I take you approach, the IDE complains about "does not implement inherited abstract member" and asks me to add the override keyword. But if I do so, there's the exception that the method must be protected internal virtual. I cannot, however, make an override method virtual.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.