tags:

views:

520

answers:

4

I've got a really simple class that is giving a strange error. The class only has 1 property and the query is really simple. The stranglest part is that this seems to happen randomly. After getting this error usually refreshing the page makes it go a way and the application doesn't get the errror again.

Could this be a problem with the database connection?

I'm getting:

[IndexOutOfRangeException: Department5_]
   System.Data.ProviderBase.FieldNameLookup.GetOrdinal(String fieldName) +4839010
   System.Data.SqlClient.SqlDataReader.GetOrdinal(String name) +67
   NHibernate.Driver.NHybridDataReader.GetOrdinal(String name) +46
   NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name) +87
   NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner) +62
   NHibernate.Loader.Loader.GetKeyFromResultSet(Int32 i, IEntityPersister persister, Object id, IDataReader rs, ISessionImplementor session) +213
   NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) +301
   NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +1422
   NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +114
   NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +205

[ADOException: could not execute query
[ select department0_.Department as Department5_ from tblDepartments department0_ where department0_.Department like 'CBS - %' ]
[SQL: select department0_.Department as Department5_ from tblDepartments department0_ where department0_.Department like 'CBS - %']]
   NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +383
   NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) +52
   NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) +183
   NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters) +102
   NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters) +684
   NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results) +816
   NHibernate.Impl.SessionImpl.List(String query, QueryParameters queryParameters, IList results) +277
   NHibernate.Impl.SessionImpl.List(String query, QueryParameters parameters) +235
   NHibernate.Impl.QueryImpl.List() +224
   DispatchBoard.Models.Repository.Find(String hql) +76
   DispatchBoard.Controllers.HomeController.Filter() +48
   lambda_method(ExecutionScope , ControllerBase , Object[] ) +39
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +178
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +24
   System.Web.Mvc.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7() +52
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +254
   System.Web.Mvc.<>c__DisplayClassc.<InvokeActionMethodWithFilters>b__9() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +192
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +399
   System.Web.Mvc.Controller.ExecuteCore() +126
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +151
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57
   System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

Here is my class

public class Department : IObject {
 public virtual string Name { get; set; }
}

The hbm file

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="DispatchBoard.Models.Department, DispatchBoard" table="tblDepartments">
     <id name="Name" column="Department" type="String" length="50">
      <generator class="assigned" />
     </id>

    </class>
</hibernate-mapping>

and here is the HQL query

var hql = "from Department d where d.Name like 'CBS - %'";
_session.CreateQuery(hql).List<T>();
+1  A: 

usually, when you get an IndexOutOfRangeException in NHibernate it is because you mapped a property twice, or mapped two properties to the same column. Check the column names.

It's possible that it occurs randomly because the conflict only shows up in a certain data constellation.

Stefan Steinegger
Thanks for the suggestion.The query is to a class that only has 1 property (Name) and no relationships. And if the refresh the page (run the query again) it will work fine. It gets the same data everytime. There are no variations to this query.In the hbm file above I have only defined the id mapping. It isn't mapped twice.
modernzombie
A: 

I wonder if NHibernate is getting confused because the entity Department has an ID column also called Department

Edit: It looks like the SQL is correct but I think it might still be worth renaming it to make things clearer.

Another theory: are your NHibernate session objects definitely being created correctly for each request? They're not thread safe.

James
A: 

You've put a length=50 in the mapping file, are you sure the database column is varchar(50), if NHibernate fetches a longer string it could be causing your error. I would usually leave the length attribute out.

reach4thelasers
A: 

We - and others - have also had this problem recently and in the past. It seems to be related to multi-threaded access to the non-thread-safe SqlConnection. The following really long (!) post contains more examples and some more detail on the issue: SQLDataReader.GetOrdinal() fails rarely with IndexOutOfRange. There bbzippo states:

"It's evident that SqlDataReader reads a result set left over from the previous query executed on the same connection a couple of seconds ago."

Unfortunately, I haven't found any real explanation of why this exception occurs suddenly in code that has been working without a problem for some time.

Some of the suggestions made in the given thread are:

  1. Turn connection pooling off, so your connection string would look like e.g. "Data Source=Sql2005;Initial Catalog=MyDbName;User Id=MyLogin;Password=MyPass;Pooling=false" (this most likely will mean a performance hit for your application but is sure to work)
  2. Refactor all static code referencing your SqlConnection instance(s) to non-static
  3. Fix possible multi-threaded access to your SqlConnections (this might not be that easy...)

I'm still trying to find the source of the error in our application but it's not that easy because I haven't been able to reproduce it outside our live environment. Matt Neerincx [MSFT] suggests in one of his answers in the above mentioned post to use different connection strings and thus different connection pools for different parts of your application to help narrow down the source of the problem.

Another read I found regarding this problem was on the hibernate forums: https://forum.hibernate.org/viewtopic.php?p=2386963, where one poster also had problems with lazy-loading in a multi-threaded scenario.

Hope this will guide anyone in the right direction for a fix.

Oliver

P.S. This is a copy of my answer to Nhibernate FieldNameLookup throws IndexOutOfRangeException

Oliver