以下属于不明来源资料:

引入

在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象。这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的,为了区分这些对象,根据对象和当前会话的关联状态,我们可以把对象分为三种:

瞬时对象:对象刚刚建立。该对象在数据库中没有记录,也不在ISession缓存中。如果该对象是自动生成主键,则该对象的对象标识符为空。

持久化对象:对象已经通过NHibernate进行了持久化,数据库中已经存在对应的记录。如果该对象是自动生成主键,则该对象的对象标识符已被赋值。

托管对象:该对象是经过NHibernate保存过或者从数据库中取出的,但是与之关联的ISession已经关闭。虽然它有对象标识符且数据库中存在对应记录,但是已经不再被NHibernate管理。

对象状态

NHibernate提供了对象状态管理的功能,支持三种对象状态:瞬时态(Transient)、持久态(Persistent)、托管态(Detached)。

1.瞬时态(Transient)

对象刚刚创建,还没有来及和ISession关联的状态。这时瞬时对象不会被持久化到数据库中,也不会被赋上标识符。如果不使用则被GC销毁。ISession接口可以将其转换为持久状态。

这像这样,刚刚创建了一个Customer对象,是一个瞬时态对象:

var customer = new Customer() { Firstname = "zhang", Lastname = "san"  };

2.持久态(Persistent)

刚被保存的或刚从数据库中加载的。对象仅在相关联的ISession生命周期内有效,在数据库中有相应记录并有标识符。对象实例由NHibernate框架管理,如果有任何改动,在当然操作提交时,与数据库同步,即将对象保存更新到数据库中。

3.托管态(Detached)

持久对象关联的ISession关闭后,这个对象在ISession中脱离了关系,就是托管态了,托管对象仍然有持久对象的所有属性,对托管对象的引用仍然有效的,我们可以继续修改它。如果把这个对象重新关联到ISession上,则再次转变为持久态,在托管时期的修改会被持久化到数据库中。

对象状态转换

在同步数据库的情况下执行下面的语句可以转换对象的状态。

测试验证对象

ISession.Contains(object):检查ISession中是否包含指定实例

重新设置ISession

private void ResetSession()

{

if (_session.IsOpen)

_session.Close();

_session = _sessionManager.GetSession();

_transaction.Session = _session;

}

1.瞬时态转换持久态

方法一:ISession.Save():保存指定实例。

[Test]

public void TransientConvertPersistentTest()

{

//瞬时态对象

var customer = new Customer() { Firstname = "zhang", Lastname = "san" };

Assert.IsFalse(_session.Contains(customer));

//仍然是瞬时态,CustomerId属性值为空

//关联ISession保存到数据库中

_session.Save(customer);

//变为持久态,由于表中CustomerId字段自动增长的,保存数据库,CustomerId字段自动加一

//经过NHibernate类型转换后返回CustomerId属性值,保证数据库与实例对象同步

Assert.IsTrue(_session.Contains(customer));

}

方法二:ISession.SaveOrUpdate():分配新标识保存瞬时态对象。

2.持久态转换托管态

方法一:ISession.Evict(object):从当前ISession中删除指定实例

[Test]

public void PersistentConvertDetachedEvictTest()

{

Customer customer = _transaction.GetCustomerById(1);

Assert.IsTrue(_session.Contains(customer));

_session.Evict(customer);

Assert.IsFalse(_session.Contains(customer));

}

方法二:ISession.Close():关闭当前ISession

[Test]

public void PersistentConvertDetachedCloseTest()

{

Customer customer = _transaction.GetCustomerById(1);

Assert.IsTrue(_session.Contains(customer));

ResetSession();

Assert.IsFalse(_session.Contains(customer));

}

3.托管态转换持久态

方法一:ISession.Update():更新指定实例。

[Test]

public void DetachedConvertPersistentUpdateTest()

{

Customer customer = _transaction.GetCustomerById(1);

//持久态对象

Assert.IsTrue(_session.Contains(customer));

//重新设置ISession

ResetSession();

Assert.IsFalse(_session.Contains(customer));

//托管态对象

//在托管态下可继续被修改

customer.Firstname += "CnBlogs";

_transaction.UpdateCustomerTransaction(customer);

//转变为持久态对象

Assert.IsTrue(_session.Contains(customer));

}

看看这个例子:在托管时期的修改会被持久化到数据库中;

注意:NHibernate如何知道重新关联的对象是不是“脏的(修改过的)”?如果是新的ISession,ISession就不能与对象初值来比较这个对象是不是“脏的”,我们在映射文件中定义<id>元素和<version>元素的unsaved-value属性,NHibernate就可以自己判断了。

[Test]

public void DetachedConvertPersistentUpdateAllTest()

{

Customer customer = _transaction.GetCustomerById(1);

//持久态对象

customer.Firstname += "zhang";

Assert.IsTrue(_session.Contains(customer));

//重新设置ISession

ResetSession();

Assert.IsFalse(_session.Contains(customer));

//托管态对象

//在托管态下可继续被修改

customer.Firstname += "CnBlogs";

//这时一起更新

_transaction.UpdateCustomerTransaction(customer);

//转变为持久态对象

Assert.IsTrue(_session.Contains(customer));

}

现在我们初步知道了对象的状态。虽然对象的状态的细节由NHibernate自己维护,但是对象状态在NHibernate应用中还是比较重要的。同时对象状态也涉及了NHibernate缓存、离线查询等内容。

01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的三种状态的更多相关文章

  1. 01-08-05【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate二级缓存:第三方MemCache缓存

    一.准备工作 [1]根据操作系统(位数)选择下载相应版本的MemCache, MemCache的下载和安装,参看: http://www.cnblogs.com/easy5weikai/p/37606 ...

  2. 01-03-02-2【Nhibernate (版本3.3.1.4000) 出入江湖】CRUP操作-Save方法的一些问题

    此文由于当时不知道NHibernate的Sava方法不是更新操作,不知道Save就是Add,造成如下荒唐的求证过程,但结论是对的 ,可报废此文,特此声明. NHibernate--Save方法: Cu ...

  3. 01-07-01【Nhibernate (版本3.3.1.4000) 出入江湖】并发控制

    Nhibernate 并发控制 [1]悲观并发控制 正在使用数据的操作,加上锁,使用完后解锁释放资源. 使用场景:数据竞争激烈,锁的成本低于回滚事务的成本 缺点:阻塞,可能死锁 [2]乐观并发控制: ...

  4. 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理

    http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 管理NHibernate二级缓存 NHibernate二级缓存由ISessionF ...

  5. 01-08-04【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之命名缓存

    http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 可以在映射文件中定义命名查询,<query>元素提供了很多属性,可以用 ...

  6. 01-08-02【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider

    第一步骤:hibernate.cfg.xml文件补上如下配置: <?xml version="1.0" encoding="utf-8"?> < ...

  7. 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的一级缓存

    缓存的范围? 1.事务范围 事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结 ...

  8. 01-06-01【Nhibernate (版本3.3.1.4000) 出入江湖】事务

    Nhibernate事务的使用: public void Add(Customer customer) { ISession session = _sessionManager.GetSession( ...

  9. 01-05-01-2【Nhibernate (版本3.3.1.4000) 出入江湖】立即加载实现--NHibernateUtil.Initialize()和添加fetch关键字的HQL查询

    相关资料: http://www.cnblogs.com/lyj/archive/2008/10/29/1322373.html 问题的提出: 1.延迟加载,可能会引起session已经关闭的异常,例 ...

随机推荐

  1. error at ::0 can't find referenced pointcut performance

    严重: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support. ...

  2. 位图文件格式及linux下C语言来操作位图文件

    说到图片,位图(Bitmap)当然是最简单的,它是Windows显示图片的基本格式,其文件扩展名为*.BMP.由于没有经过任何的压缩,故BMP图片往往很大.在Windows下,任何格式的图片文件都要转 ...

  3. 麦子学院Android开发Java教程ClassCastException 错误解析

    现在Java编程中经常碰到ClassCastException 错误,ClassCastException 是 JVM 在检测到两个类型间的转换不兼容时引发的运行时异常.此类错误通常会终止用户请求.本 ...

  4. CSS精粹之布局技巧

    1.若有疑问立即检测 在出错时若能对原始代码做简单检测可以省去很多头痛问题.W3C对于XHTML与CSS都有检测工具可用,请见http://validator.w3.org 请注意,在文件开头的错误, ...

  5. 将word中的“空格” 转换为换行符

  6. 使用awstats分析iis站点的日志

    环境:win7 + iis7 + perl(ActivePerl-5.20.1.2000) + awstats 7.3 一.找到iis日志所在目录 建议全部都打勾 二.安装perl AWStats是p ...

  7. string和json转换的简单应用

    import com.alibaba.fastjson.JSON; String strjson = request.getParameter("param"); //url-js ...

  8. PHP自动识别字符集并完成转码详解

    话不多说,直接上函数,这个函数是用来对字符串进行检查和转码的.需要的朋友可以过来参考下 因为自己使用字符编码一般的是utf-8编码,但如果对方的博客使用gb2312编码的话,POST过来就会出现乱码( ...

  9. 团队自动化环境搭建与管理--php博弈

    我是方少,很开心与大家日后与大家交流技术上面的一些想法和一些业务上的分享.以前从来没写过博客,因为觉得不重要吧,如今觉得有必要沉淀一些想法和回忆.好了费话不多说. 先上图: 业务问题:在每次新伙伴加入 ...

  10. String与StringBuffer对象问题

    下面的代码创建了三个String对象,其中pool中一个,heap中两个 String s1 = new String("abc"); String s2 = new String ...