我想对我在NHibernate上使用INSERT命令和无状态会话时发现的行为有一个意见(NB。我使用NHibernate 2.1.2)
案例是这个
//STATEFULL SESSION
var session = sessionFactory.OpenSession()
using(var transaction = session.BeginTransaction()){
var entity = new MyEntityType();
entity.Id = 1;
session.Save(entity);
var entity2 = session.Get<MyEntityType>(1);
//OK! It returns saved entity...as I expect
transaction.Commit();
}
但......在无状态会话中,行为发生了变化......
//STATELESS SESSION
var session = sessionFactory.OpenStatelessSession()
using(var transaction = session.BeginTransaction()){
var entity = new MyEntityType();
entity.Id = 1;
session.Insert(entity);
var entity2 = session.Get<MyEntityType>(1);
//entity2 IS NULL!!! Why?
transaction.Commit();
}
我的问题是......如何检查我是否已在无状态会话的交易范围内插入了一个项目?
答案 0 :(得分:3)
嗯,无国籍者是......无国籍的。因此,没有会话缓存可以让您从内存中返回插入的实体。
现在,为什么不在数据库中读取?因为它还没有出现!
您很可能已启用批处理(adonet.batch_size
xml配置参数,或通过代码Environment.BatchSize
配置属性,或者在会话工厂级别启用时未通过IStatelessSession.SetBatchSize(int)
禁用它)。启用批处理后,如果您的NHibernate数据库驱动程序支持它,则DML操作尽可能地一起批处理,直到配置的批处理大小,然后刷新到数据库。
因此可能会发生无状态会话的冲洗:
s.GetSessionImplementation().Flush();
如果您希望立即将Insert
发送到数据库,请禁用批处理。将其设置为0
将禁用它。
但是你为什么要首先使用无状态会话?可能以有效的方式插入大量实体。在这种情况下,禁用批处理将是您的目的。
因此,您可以转而使用会话GetSessionImplementation()
方法公开的内部会话接口,并明确地Flush
它。但是,直接调用内部可能会产生未定义的行为,因此这不是推荐的做法。