2

Session.Clear() に問題があります。このステートメントは、UOW やキャッシュなどで行われたすべての変更を完全にリセットする必要があることを理解しています。問題はそうではないことです。私のシナリオは、以下のテストに示されています。アイテムに追加すると、それらの間に依存関係があり、他のアイテムが依存しているアイテムを削除しようとします。これにより、正しい例外が発生します。その後、セッションをクリアします。最後に、データベースに新しい項目を追加しようとします。NHibernate をフラッシュすると、失敗した削除ステートメントをもう一度実行しようとします。Session.Clear() の使用を誤解していますか? それとも、ここで何か他のものを見逃していますか?

    [Fact]
    public void Verify_Cant_Clear_Delete()
    {
        var session = SessionFactory.OpenSession();

        var category = new ManufacturerCategory { Name = "category" };
        var man = new Manufacturer { Category = category, Name = "man" };

        session.Save(category);
        session.Save(man);
        session.Flush();

        try
        {
            // this will cause
            // NHibernate.Exceptions.GenericADOException: could not execute batch command.[SQL: SQL not available]
            // ---> System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "ManufacturerCategoryId". 
            // The conflict occurred in database "LabelMaker-Tests", table "dbo.Manufacturers", column 'Category_id'.

            session.Delete(category);
            session.Flush();

        }
        catch (Exception ex)
        {
            // This should clear the session
            session.Clear();    
        }

        try
        {
            var category2 = new ManufacturerCategory { Name = "category 2" };
            session.Save(category2);
            session.Flush();
        }
        catch(Exception ex)
        {
            // this will cause ONCE AGAIN cause
            // NHibernate.Exceptions.GenericADOException: could not execute batch command.[SQL: SQL not available]
            // ---> System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "ManufacturerCategoryId". 
            // The conflict occurred in database "LabelMaker-Tests", table "dbo.Manufacturers", column 'Category_id'.

            Assert.True(false);
        }
    } 
4

2 に答える 2

2

トランザクションを使用し、休止状態の例外でトランザクションをロールバックする必要があります...

ISession の特定のメソッドは、セッションを一貫した状態のままにしません。

http://nhibernate.info/doc/nh/en/index.html#manipulatingdata-exceptions

または、dispose() を介してトランザクションを暗黙的にロールバックさせます...

using (ISession sess = factory.OpenSession())
using (ITransaction tx = sess.BeginTransaction())
{
    // do some work
    ...
    tx.Commit();
}

Delete() メソッドは、上記の引用で示唆されている一貫性のない状態メソッドの 1 つであると思います...

于 2013-01-03T21:04:17.287 に答える
1

についてのあなたの仮定ISession.Clear()は正しくありません。

特に、例外が発生するとすぐに、セッションを破棄する必要があります。Clear()状態は修正されません ( 9.8 例外処理を確認してください) 。

また、dotjoe が述べたように、トランザクションを使用して作業を行う必要があります。

于 2013-01-06T00:49:56.363 に答える