2012-02-16 4 views
2

私のアプリケーションでNHibernateを使用していて、次のような状況があります。 (ここでの状況は、理解のためにはるかに単純化されていることに注意してください)なぜSessionからオブジェクトを追い出しても、データベースへの変更はコミットされません。

オブジェクトはデータベースから照会されます。 Session.Update()を使用して編集および更新されます。オブジェクトは、トランザクションがコミットされる前にセッションから退去されます(Session.Evict(obj)を使用)。予想される結果は、変更がデータベースに保持されることです。

これは、NHibernate identityカラムとして自分のIdカラムを使用したときに正常に動作していました。 最近、ID列を非同一に変更しました。結果として、前述のシナリオは、Evict前に明示的にSession.Flush()を呼び出さない限り、データベースに保持されません。

誰かがこの行動の理由を指摘/説明できますか?

このリンクNHibernate Session.Flush & Evict vs Clearは、私にはわかりにくいエビクトとアイデンティティの列について何か言及しています。

答えて

2

NHibernateは、エンティティを即座にデータベースに保存するようにします。session.Save() IDなしで、挿入をバッチして全体として送信することができます。 Evictは、オブジェクトのすべての情報をセッションから削除します。したがって、たとえセッションが知りませんでしたとしても、アイデンティティを持っている間はエンティティについて忘れてしまいます。あなたは

  • 最良の選択肢である

を完了したトランザクションの後

  • コールsession.Flush()
  • Evict前に立ち退かが依存 Flushmode.Auto(軍の即時フラッシュ)を設定することができますことを改善する

    文脈

    9

    ワークフローが正しくありません。

    最初に、データベースからオブジェクトを取得すると、session.Update(entity)は何も行いません。 Flush/Commit

    次に、Evictは、セッションがオブジェクトに対して持つすべての知識を削除するため、変更が適用されることはありません。通常の状態でこの方法を使用することはほとんどありません。セッションが正しく処理されていないと思われます。

    第三に、identity原因を使用してSaveですぐに起こることを挿入という事実は特に制限はなく、機能です。

    正しいワークフローは次のとおりです。

    using (var session = factory.OpenSession()) 
    using (var transaction = session.BeginTransaction()) 
    { 
        var entity = session.Get<EntityType>(id); 
        entity.SomeProperty = newValue; 
        transaction.Commit(); 
    } 
    

    正確な構造(using文など)は、デスクトップアプリケーションに変更することができますが、基本的な考え方は同じです。

    +0

    ディエゴ、あなたは正しいです。私たちはこのような「悪い」手法に頼らざるを得ませんでした。なぜなら、読み込まれたセッションには多くのオブジェクトがロードされていたからです。トランザクションがコミットされると、変更が進むまでに時間がかかりました。したがって、オブジェクトを照会した後にオブジェクトを追い出すと、セッション内のオブジェクトを減らすことができると考えました。後で更新されるオブジェクトは、自動的にセッションに自動的に再接続されます。 私たちの最初の間違いは、このためにNHibernateを使用することでしたが、私たちのシステムからそれを削除できるようになるまで、私たちは物事をスピードアップするためのいくつかの回避策を探しています... – Zuber

    +0

    この特定の問題は、更新は何とかデータベースにフラッシュされ、オブジェクトを暴露した後でさえ、私はその変更を見ることができた。 NHibernateのAutoFlushは、ID列に依存するいくつかのロジックを使用していましたか? ところで、これはWebアプリケーション内にあるので、すべてのリクエストに対してセッションを作成し、最後にコミットします。このアプリは、ユーザーが独自のIronPythonスクリプトを作成するminsalesforce.comのようなものです。それは、私たちがEvictするセッションに多くの読み込み専用オブジェクトを追加したことです。それは我々にいくつかのパフォーマンスをもたらしました。 – Zuber

    +0

    私は、これらのエビクトが起こる前にセッションをフラッシュすることによって、この特定の問題を解決しました。このコードは広範囲に呼び出されるわけではないので、今は大丈夫です。 しかし、我々のプロジェクトのための最善の勧告は、この層のNHibernateを置き換えることです – Zuber

    関連する問題