我有以下代码:
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中,它说,
确保你理解的语义 同花顺()。刷新同步 内存中的持久存储 更改但不是反之亦然。
那么,我如何让内存对象得到更新?我知道每个会话都会缓存对象。但是执行UniqueResult()或List()应该与db同步并使缓存无效,对吗?
我无法理解的是,为什么会话报告陈旧数据?
答案 0 :(得分:0)
这取决于你做了什么样的操作。 NHibernate默认具有一级缓存。它使用缓存来按ID获取实体,依此类推。
答案 1 :(得分:0)
对象的内存视图(1级缓存)是每个会话。
A接受ISessionFactory并使用自己的事务范围打开自己的会话。
即使SomeFunc中使用的ISession的内容被刷新到数据库,_session也不会看到这些更改,直到它的1级缓存被清除。
答案 2 :(得分:0)
你有两个会话。一个是A.SomeFunc,另一个是你的单元测试。每个会话在会话缓存(第一级缓存)中都有自己的实体实例。会话不会相互通信或协调。当一个会话写入其更改时,不会通知另一个会话。它的会话缓存中仍然有自己过时的实例。
当您调用_session.Clear()时,通过清除会话缓存使会话“忘记”。当您重新查询时,您正在从数据库中读取新数据,其中包括来自其他会话的更改。