1
votes

I started a new project and for this project i wanted to use BasicSample (NHibernate best practise, http://www.codeproject.com/Articles/13390/NHibernate-Best-Practices-with-ASP-NET-1-2nd-Ed) i haven´t used this before and now i get problems. In this project i use NHibernate 3.3.1 and modified the source code from BasicSample to use my entieties. I get this error for every class model (just showing for the class "Month"):

System.TypeInitializationException was unhandled by user code

Message=The type initializer for 'Nested' threw an exception. Source=Project.Data TypeName=Nested StackTrace: at Project.Data.NHibernateSessionManager.get_Instance() in Project.Data\NHibernateSessionManager.cs:line 28 at Project.Web.NHibernateSessionModule.BeginTransaction(Object sender, EventArgs e) in App_Code\NHibernateSessionModule.cs:line 27 at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) InnerException: NHibernate.InvalidProxyTypeException Message=The following types may not be used as proxies: Project.Core.Domain.Calendar.Month: method Equals should be 'public/protected virtual' or 'protected internal virtual' Project.Core.Domain.Calendar.Month: method IsTransient should be 'public/protected virtual' or 'protected internal virtual' Project.Core.Domain.Calendar.Month: method get_Year should be 'public/protected virtual' or 'protected internal virtual' Project.Core.Domain.Calendar.Month: method set_Year should be 'public/protected virtual' or 'protected internal virtual' Blockquote

the class looks like:

public class Month : DomainObject<int>
{
    private Year _year;
    public Year Year
    {
        get { return _year; }
        set { _year = value; }
    }

    private string _monthName; 
    public string MonthName
    {
        get { return _monthName; }
        set { _monthName = value; }
    }

    private IList<Consumption> consumptions = new List<Consumption>();
    public IList<Consumption> Consumptions
    {
        get { return new List<Consumption>(consumptions).AsReadOnly(); }
        protected set { consumptions = value; }
    }

    public Month()
    { }

    public override int GetHashCode()
    {
        return (GetType().FullName + "|" +
                MonthName.GetHashCode()).GetHashCode();
    }

Does anoyone know what the problem could be? I have been crosschecking my project and the BasicSample project but i can´t find anything that missmatch.

2.Can someone explain for me how to use the GetHashCode from DaomainObject because i don´t know how to use this one in every class= Should every property in the class be added here?

I hope someone can help me.

2

2 Answers

3
votes

The problem is contained in your exception stack trace. You need to read them more carefully:

The following types may not be used as proxies:
Project.Core.Domain.Calendar.Month: method Equals should be 'public/protected virtual' or 'protected internal virtual'
Project.Core.Domain.Calendar.Month: method IsTransient should be 'public/protected virtual' or 'protected internal virtual'
Project.Core.Domain.Calendar.Month: method get_Year should be 'public/protected virtual' or 'protected internal virtual'
Project.Core.Domain.Calendar.Month: method set_Year should be 'public/protected virtual' or 'protected internal virtual'

What it says is basically, that you need to make all public and protected members of your class virtual, otherwise lazy loading won't work.


GetHashCode:
The hash code of an instance should not change over the course of its lifetime, therefore you shouldn't include properties that can be changed.

2
votes
  1. NHibernate uses lazy loading by default. It performs it by creating proxy classes from your entities - inheriting from your entity and overriding it's members. In order for this to work, you need to mark all of your entity members as virtual. That was what it complains about in exception message.

  2. As for GetHashCode, you should implement it in DomainObject and only use Id in GetHashCode overrides. You should also override Equals. Here you can find reasons why: NHibernate: Reasons for overriding Equals and GetHashCode.