0

Randomly NHibernate seems to fail with an IndexOutOfRange Exception. The code works most of the, time but causes random application crashes.

    public T GetByID<T>(Guid Id) where T : Modules.Common.EntityBase
    {
        try
        {
            ISession session = NHibernateHelper.GetCurrentSession();
            var product = session
                .CreateCriteria(typeof(T))
                .Add(Restrictions.Eq("Id", Id))
                .UniqueResult<T>();
            return product;
        }
        catch (HibernateException ex)
        {
            NHibernateHelper.CloseSession();
            throw;
        }
    }

I'm using the code on a WCF Service where ISessions are managed for each individual httpcontext, so i don't think it's due to thread safety. The Exception comes from DataReader so I'm going to guess that it is comming from the UniqueResult line.

Here is the get Current Session function

    public static ISession GetCurrentSession()
    {
        if (HttpContext.Current == null)
        {
            lock (sessionLock)
            {
                if (_session == null)
                    _session = sessionFactory.OpenSession();
            }
            return _session;
        }

        HttpContext context = HttpContext.Current;
        ISession currentSession = context.Items[CurrentSessionKey] as ISession;

        if (currentSession == null)
        {
            currentSession = sessionFactory.OpenSession();
            context.Items[CurrentSessionKey] = currentSession;
        }

        return currentSession;
    }
Marty Trenouth
  • 3,712
  • 6
  • 34
  • 43
  • Where have you gotten with debugging this exception? On what line is it thrown? If I had to guess, I'd say it is coming out of the `NHibernateHelper.GetCurrentSession()` method, unless one of the entities that you are fetching has some setter logic that is throwing when NHibernate tries to assign values. – Jay Dec 14 '10 at 01:37
  • I agree with @Jay. Could you please post your GetCurrentSession() code ? – Mahesh Velaga Dec 14 '10 at 01:41
  • 1
    this is unrelated to the problem, but if you have the Id, you should use `session.Get(Id)`, not a Criteria query. – Diego Mijelshon Dec 14 '10 at 02:34
  • @Diego. I'll update it to that looks better. @Jay... it's comming somewhere from DBReader. I'll post the StackTrace next time I get the error. – Marty Trenouth Dec 14 '10 at 16:35
  • So apparently with WCF HttpContext.Current == null, which blows to smithereens the per request session management that I put in place. Any ideas on the best way to store a session for a call? – Marty Trenouth Dec 14 '10 at 22:12

2 Answers2

1

maybe a long shot, but check this IndexOutOfRangeException Deep in the bowels of NHibernate

Community
  • 1
  • 1
Jaguar
  • 5,929
  • 34
  • 48
  • I've already gone through that all columns are unique (actually using Fluent to configure and I'm not changing the column names. – Marty Trenouth Dec 14 '10 at 16:33
  • interesting, does the error appear only when calling the method 'GetByID' ? (also, provide a stacktrace) – Jaguar Dec 14 '10 at 20:38
0

Turns out that in WCF HttpConext is null, which because I based the thread separation on the current HTTPContext (assuming that it functioned like a regular web app).

Saw a tutorial on Getting NHibernate to work with WCF that looked like it may work, but had problems implementing the solution. However it REALLY seems complex to use this method in a per request scenario... there's like 5 object, it requires modifying each of the services.

Point to note that if they are working in only an HTTP environment you can use the AspNetCompatibilityRequirements attribute and config section to get WCF to have HTTPContext values.

Class:

[System.ServiceModel.Activation.AspNetCompatibilityRequirements(RequirementsMode = System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Required)]

public class CaseService : ServiceBase, ICaseService
{
...
}

Web.config:

 <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    ...
 </system.serviceModel>

I read somewhere that a WCFSessionProvider (or something to that effect) is provided in NHibernate 3.0 so I'll wait for that solution to make the real solution.

Marty Trenouth
  • 3,712
  • 6
  • 34
  • 43