2009-11-03 5 views
13

私は奇妙なエラーを与えている本当にシンプルなクラスを持っています。クラスは1つのプロパティしか持たず、クエリは本当に簡単です。奇妙な部分は、これはランダムに発生するようです。通常、このエラーが発生した後、ページをリフレッシュするとエラーになります。アプリケーションはエラーを再度取得しません。NHibernate System.IndexOutOfRangeException

これはデータベース接続に問題がありますか?

私が取得しています:ここでHQLクエリをさ

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

HBMファイル私のクラスここで

[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 

<?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> 

をされており、

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

このクラス/マッピング/クエリは完了していると言えますが、ここには何もありません。 –

+0

異なるクラスを使用してこの前に発生するクエリがいくつかありますが、これは完全なクエリとマッピングです。それは私には意味がありません。 – modernzombie

+0

問い合わせの前に、NHibernateはセッションをフラッシュして、更新されたデータに問い合わせるようにします。これは、このクエリの前に行うメモリ内の変更が原因で発生する可能性があります。スタックトレースはこのようには見えませんが、引き続きフラッシュ中またはクエリ中に発生するかどうかを確認するために、クエリの前にsession.Flush()を呼び出して試してください。とにかくこの他のクラスのマッピングを確認してください。 –

答えて

11

通常、NHibernateでIndexOutOfRangeExceptionが取得されたのは、プロパティを2回マッピングしたか、同じカラムに2つのプロパティをマップしたためです。列名を確認してください。

コンフリクトが特定のデータコンスタレーションにしか表示されないため、ランダムに発生する可能性があります。

+0

提案していただきありがとうございます。 クエリは、1つのプロパティ(Name)と1つの関係しか持たないクラスに対するものです。そして、ページをリフレッシュして(再度クエリを実行すると)うまくいくでしょう。それは毎回同じデータを取得します。このクエリにはバリエーションはありません。 上記のhbmファイルでは、IDマッピングのみを定義しました。それは2回写像されません。 – modernzombie

+0

私は別の方法でマッピングプロパティを混乱させました。あなたのコメントは正しい方向に私を指摘しました。ありがとう! – thebiggestlebowski

+0

私の場合、idParentプロパティと多対1の親で、同じ列を使用していました。ありがとう!正常に動作します。 –

0

マッピングファイルに長さ= 50を入れました.Hibernateが長い文字列をフェッチすると、エラーが発生する可能性があります。データベースの列はvarchar(50)ですか?私は通常、長さ属性を残しておきます。

7

われわれや他の人たちも、最近、かつてこの問題を抱えていました。それは非スレッドセーフSqlConnectionへのマルチスレッドアクセスに関連しているようです。次のは本当に長いです(!)投稿にはさらに多くの例と問題の詳細が含まれています:SQLDataReader.GetOrdinal() fails rarely with IndexOutOfRange。状態がありbbzippo:

「それはSqlDataReaderのは数秒前に同じ 接続で実行 前のクエリから残っ 結果セットを読み込むことは明らかです。」

残念ながら、私はしばらくの間問題なく動作していたコードでこの例外が突然発生する理由について、実際の説明は見つかりませんでした。

指定されたスレッドで行われた提案のいくつかは、次のとおりです。オフプーリング

  1. 回して接続するので、接続文字列は、例えば次のようになりますnon-static
  2. にごSqlConnectionインスタンス(複数可)を参照し"Data Source=Sql2005;Initial Catalog=MyDbName;User Id=MyLogin;Password=MyPass;Pooling=false"(これが最も可能性の高いアプリケーションのパフォーマンスヒットを意味するが、動作するはずですします)
  3. リファクタリングすべてstaticのコードでは、あなたのSqlConnection sまで可能マルチスレッドアクセス(これを修正します)簡単にはできないかもしれません...)

私はまだアプリケーションのエラーの原因を見つけようとしていますが、私は実際の環境の外では再現できないため、簡単ではありません。上記の投稿のMatt Neerincx [MSFT] suggests in one of his answersを使用して、アプリケーションのさまざまな部分に異なる接続文字列と異なる接続プールを使用して、問題の原因を絞り込んでください。

この問題に関するもう1つの読者は、休止状態のフォーラム:https://forum.hibernate.org/viewtopic.php?p=2386963にありました.1つのポスターには、マルチスレッドシナリオでの遅延読み込みにも問題がありました。

これは、修正のための正しい方向に誰かを導くことを望みます。

オリバー

P.S.これは私の答えのコピーですNhibernate FieldNameLookup throws IndexOutOfRangeException

+0

私はあなたのソリューションがNHibernate以上で動作すると思います。具体的には、AspDotNetStorefrontに問題がある場合。 – CaptainBli

+0

UCommerceとUmbracoを使用します。 UCommerceはNHibernateを使用します。このIndexOutOfRangeExceptionエラーは何千もあります。プールすることを偽にすると、今解決されているようだ... – Hans

2

私は、私たちのシステム(nHibernateを使用しない)でGetOrdinalエラーの原因を追跡しようとしました。私たちの場合、接続文字列に "Enlist = False"を追加すると、問題は完全に消えました。我々は1日あたり約160のエラー(主にGetOrdinalエラー)から、昨日は26エラーになりました.1つのGetOrdinalではありません。

Enlist引数(既定ではTrue)は、ADOに接続をグループ化し、それらを原子的に単一のトランザクションとして処理するように指示しますが、動作していないようです。コードにはトランザクション処理の指示は全くありませんが、ADOは接続をグループ化し、予期せぬ結果をデータに生じさせていました。

コード内でSQLトランザクションを処理していない場合は、この設定を試してみてください。これと同じように肯定的な結果が得られるかもしれません。

Iが非NULL可能性(すなわち、整数)にヌル値をマッピングしようとしたとき、私はこのエラーを得ているマイク

4

。 SQL値がnullでないことを確認するか、C#プロパティをnullableにしてください(public virtual int? NumberOfPoints { get; set; }

0

通常、列名とマッピングプロパティ名が正しく一致しないと、システムはIndexOutOfRangeException例外をスローします。

0

私はしばらくの間、非常に似たエラーで苦労しました。私はSession.CreateSQLQuery(文字列)で作成された "ネイティブSQL"クエリからエラーを取得していました。以前はよく似たクエリを使用していましたが、今回はサブクラスを持つエンティティタイプをクエリしていて、データベースのクラスごとにテーブルとしてマップされていました。

私は通常のクエリを実行すると、NHibernateにSQLを生成させることに気付きました。「subclass_table.Parent_class_idがnullでない場合は1、parent_class.Idがnullでない場合は0のようにとしてclazz_ "。

ので、修正前に私のクエリは、このようなものだった:排他テーブルロックを強制

SELECT TOP 1 * 
FROM Table WITH (TABLOCKX) 
WHERE Column = 'Value' 

は(私が最初の場所で「ネイティブSQL」を使用してクエリをやっている理由です。.. )

「clazz_」という列を追加するだけで、作業が始まりました。この場合、私は結果がサブクラスのインスタンスが含まれないことを確実に知るので、私はちょうどゼロとして値をハードコーディングしています:

SELECT TOP 1 *, 0 as clazz_ 
FROM Table WITH (TABLOCKX) 
WHERE Column = 'Value' 

結果はのインスタンスを含めることが可能である場合サブクラスでは、これはもっと複雑になります。それから私は実際には、サブクラスのテーブルのための左外部結合と、NHibernateがそれを使用する方法のCASE句を含める必要があります。

関連する問題