2010-12-08 11 views
2

私はNHibernateプロジェクトで作業しています。以前はコレクションを読み込むことができませんでした(http://stackoverflow.com/questions/4213506/c-hibernate-criteria-loading-コレクション)、私は今データの使用に問題があります。C#NHibernate with Spring LazyInitializationExceptionデータを使用するとき

私はNHibernateとSpring.Netフレームワークとの組み合わせでC#を使用していますが、私は 'ordercredit'をロードしてからordercreditのオブジェクトにアクセスした後にLazyInitializationExceptionを取得します。

[Transaction(TransactionPropagation.Required, ReadOnly = true)] 
public OrderCredit GetOrderCredit(long ordercreditid) 
{ 
    var creditrules = Session.CreateCriteria(typeof(OrderCredit)); 
    creditrules.Add(Restrictions.Eq("Id", ordercreditid)); 
    return creditrules.List<OrderCredit>()[0]; 
} 

私は私のローカルマシン上でこれを実行する

、すべてのもの:

OrderCredit oc = CreditService.getOrderCredit(ordercredit.Id); 

私はロードに使用するコードは、DAOの実装を使用して行われます:

私はOrderCreditを取得するためにこのコードを使用しますうまく動作し、実際にはそれらの 'ordercredits'のリストをロードすることを意図していたが、それも間違っていたので、私はより簡単なステップを最初に試した。

'OrderCredit'内のオブジェクトは[OneToMany]として定義されています。私はTESTSERVERでこれを置く

、およびロードされたOrderCreditの「OrderObject」オブジェクトにアクセスしようと、私はエラーを取得:

NHibernate.LazyInitializationException:初期化[.OrderObjectの#5496522]初期化できません-Couldプロキシ - セッションなし。失敗

コード:

Log.Debug(oc.OrderObject.Name); 

コード作品:

Log.Debug(oc.Id); 

これはOrderCreditの一部だ任意のオブジェクトのために起こりますが、私はOrderCreditのプロパティフィールドにアクセスすることができています(たとえばOrderCredit.Id)。

また、メソッドを呼び出す元の関数にデータを返す前にオブジェクトにアクセスすると、情報にアクセスできるように情報がキャッシュされます。

私はLazyをオフにするなど、この問題について多くのことを読んだことがありますが、それも私にとってはうまくいきませんでした(または間違った場所でやった)。

私が最も苛立っているのは、実際にローカルマシン上で動作し、テストサーバでは動作しないという事実です。私は何が間違っていますか?

ご協力いただきまして誠にありがとうございます。

第一更新:

私は1 ordercreditをロードするデフォルトの方法を使用して、今GenericDaoを使用しています。 Idによって1 ordercreditを読み込むために、次のコードを使用します。

OrderCredit oc = GenericService.Load<OrderCredit>(Id); 

GenericDAO内のコードは以下の通りであるが、それは私がordercreditに添付オブジェクトにアクセスすることができる午前意味し、終了またはセッションを切断しません:

[Transaction(TransactionPropagation.Supports, ReadOnly = true)] 
public T Load<T>(long id) where T : ISaveableObject 
{ 
    var obj = Session.Load<T>(id); 
    return obj; 
} 

これがされこの質問の前半に含まれていた機能とほぼ同じコードです。

セッションが終了する可能性があるかどうかわからないので、今は本当に混乱しています。私はそれが動作するように今作業しますが、私は後でそれを変更したいので、私はコレクション全体を呼び出し、各ループのためにアクセスするために私の関数を使用することができます。

現在、私は「getOrderCredits」関数を使用してOrderCreditオブジェクトのリストを取得し、foreachではIdを取得し、GenericDao.Loadを使用して実際のアイテムを取得し、オブジェクトなどにアクセスできます。もちろん、これはそれが必要であり、必要とされる方法ではありません。

これを解決すれば驚くだろう。

+0

あなたはNHセッションを開いて閉じますか?このエラーメッセージは、遅延ロードが試行されるまでにNHセッションが終了したことを示しています。 –

+0

これは私が働いているプロジェクトの拡張です。トランザクションは、Hibernate/Springトランザクションマネージャによって処理されます。私は別のものを試していて、小さな仕事にやってきました。私は私の質問を編集し、この情報とコードを追加します。私はそれが自分の状況で間違っているかどうか分かりません。 – Honnes

答えて

4

これはNHibernateを使用するときに人々がよく抱く問題です。あなたはあなたがあなたの参照先エンティティ のプロパティにアクセスしようとするセッション

  • を閉じて別のエンティティ
  • を参照し、データベースからエンティティをロードするセッション
  • を開く

    1. :ので、それが起こります
    2. NHibernateは、親エンティティをロードしたセッションと同じセッションを使用してデータベースから遅延させようとします。
    3. セッションは閉じられているので、NHibernateはwoahのような例外をスローします。

    あなたがここにいくつかのオプションがあります:

    1. は、好ましくは、あなたの厳密な制御を与える作業パターンの単位のようなものを使用して、長いオープンセッションをしてください。あなたが照会すると
    2. は熱心にあなたの参照エンティティをロード:

    をお使いの場合には、スプリングがあなたのためにトランザクションを管理しているとして第二のオプションは、おそらく最速/最も簡単な解決策です。

    var creditrules = Session.CreateCriteria(typeof(OrderCredit)); 
    creditrules.Add(Restrictions.Eq("Id", ordercreditid)) 
        .SetFetchMode("OrderObject", FetchMode.Eager); 
    

    あなたがOrderCreditをロードするとき、これはOrderObjectをロードします。

  • +0

    あなたのご意見ありがとうございます!もう私はそのプロジェクトに取り組んでいないので、今はもうテストすることができないと付け加えなければなりませんが、私はあなたの意見に感謝します。私はそれをテストすることができないので、あなたの答えを受け入れられた答えとするのはまったく正しいことではありませんか? – Honnes

    +0

    私は受け入れを追いかけておらず、ただ助けようとしています。 – jonnii

    関連する問題