为什么需要session.Clear()来反映此示例中数据库中的更改?

问题描述 投票:3回答:3

我有以下代码:

public class A
{
    private ISessionFactory _sf;
    A(ISessionFactory sf)
    {
        _sf = sf;
    }

    public void SomeFunc()
    {
        using (var session = _sf.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            // query for a object
            // change its properties
            // save the object

            transaction.commit();
        }
    }
}

在单元测试中,其用法如下>>

_session.CreateCriteria ... // some setting up values for this test

var objectA = new A(_sessionFactory);
objectA.SomeFunc();

// _session.Clear();

var someVal = _session.CreateCriteria ... // retrieve value from db to 
                                   //check if it was set to the 
                                   //proper value
                                   //it uses a restriction on a property
                                   //and a uniqueresult to get the object.
                                   //it doesnt use get or load.

Assert.That(someVal, Is.EqualTo(someOtherValue)); // this is false as long 
                                   //as the _session.Clear() is commented. 
                                   //If uncommented, the test passes

我正在测试sqlite文件数据库

。在测试中,我对数据库进行了一些更改以正确设置数据库。然后,我调用SomeFunc()。进行所需的修改。一旦我回到测试中,该会话就不会获得更新的值。它仍然返回调用SomeFunc()之前的值。我必须执行_session.Clear()才能使更改反映在测试中的断言中。

为什么需要这个?

编辑:cache.use_second_level_cache和cache.use_query_cache都设置为false

Edit2

:在NH Documentation中阅读以下语句。

[ISession有时会执行所需的SQL语句同步ADO.NET连接的状态与持有的对象的状态在记忆中。冲洗过程发生默认情况下,在以下几点

* from some invocations of Find() or Enumerable()
* from NHibernate.ITransaction.Commit()
* from ISession.Flush()

[在section 10.1中说,

确保您了解Flush()。冲洗同步具有内存的持久性存储更改,但反之亦然

所以,如何获取内存中的对象以进行更新?我了解每个会话都会缓存对象。但是执行UniqueResult()或List()应该与db同步并使缓存无效,对吧?

我不明白的是,为什么会话报告陈旧数据?

我有以下代码:public class A {private ISessionFactory _sf; A(ISessionFactory sf){_sf = sf; } public void SomeFunc(){使用(var session = _sf ....

nhibernate session
3个回答
0
投票

它取决于您执行何种操作。 NHibernate默认具有一级缓存。它使用高速缓存通过ID等获取实体。


0
投票

对象的内存视图(1级缓存)是每个会话的。


0
投票

您有两个会话。一个在A.SomeFunc中,另一个在您的单元测试中。每个会话在会话缓存(一级缓存)中都有自己的实体实例。会话之间无法相互通信或协调。当一个会话写入其更改时,不会通知另一会话。它的会话缓存中仍然拥有自己的过时实例。

© www.soinside.com 2019 - 2024. All rights reserved.