NHibernate中对同一个对象的Lazyload要设置一致

在NHibernate中出于性能的考虑,经常使用Lazyload的方式来加载关联的对象,关于什么是Lazyload,以及怎么使用,可以参见博客园中的文章,比如:http://www.cnblogs.com/lyj/archive/2008/10/28/1321494.html

常用NHibernate.ByteCode.Castle动态代理来实现Lazyload,使用该程序集会在运行时创建实体对应的代理类,如果实体使用了继承关系,并通过NHibernate来映射,那么动态代理类在类型转换时会有问题。

比如在C#中定义了一个Node类,然后有个State类继承自Node类,然后有Flow.Node引用了这个类,同时我还在Task.Node中引用了这个类。并且在默认情况下启用了Lazyload。在通过Flow对象获得Node对象时,会返回'Castle.Proxies.NodeProxy'对象,而这个对象是没办法转换成State对象的,所以会抛出如下的异常:

Unable to cast object of type 'Castle.Proxies.NodeProxy' to type 'Xxx.Core.Model.Definition.State'.

那么怎么办呢,只有不使用Lazyload,所以我将Flow.Node的加载方式改为立即加载,然后这个异常就没有了。但是今天在调用另外的方法,然后在调用Flow.Node时,又出现了这个异常,这让我十分郁闷,我明明指定了Flow.Node是立即加载的,那么怎么还是会被系统转换为NodeProxy了呢?

经过研究发现,应该是Task.Node没有被设置为立即加载的原因。我在调用Flow.Node之前,调用了Task对象,所以NHibernate根据Task的Mapping设置,将Node设置为动态代理类,同时将Node缓存到了Session中,然后再调用Flow.Node时,系统就会先从缓存中查找是否有对应的Node对象,结果正好有NodeProxy的缓存,所以就直接返回NodeProxy给Flow.Node了,系统根本没有检查Flow.Node是不是立即加载还是懒加载。

所以要解决这个异常的话,有两个办法,一种是将Task.Node也设置成为立即加载,那么就不会有NodeProxy对象在缓存中。另外一种办法就是不在Task中引用Node对象,我采用的是第二种方法,在Task中,其实我只需要Task.NodeId就够了,不需要再加载Node对象进来。

总的来说,如果在NHibernate中用到了继承类,如果同时用到了Lazyload,那么在转换类型时就可能抛出异常。解决办法就是将Lazyload取消,改为立即加载。如果有多个实体引用了该对象,那么就需要将这个对象的引用的Lazyload方式设置为一致的,对不使用Lazyload或者减少对对象的引用。

时间: 2024-12-20 15:13:36

NHibernate中对同一个对象的Lazyload要设置一致的相关文章

请教个问题,在VPC中,同一个subnet下,如何设置其它的instance通过同一个subnet下的某个NAT instance来访问internet?

问题描述 请教个问题,在VPC中,同一个subnet下,如何设置其它的instance通过同一个subnet下的某个NATinstance来访问internet? 解决方案 解决方案二:在VPC中有一个叫routetable的东西可用设置你想要的任何形式的路由.你只需要将subnet的route设置为从NATinstance走就可以了

HTML中的window对象和JavaScript中的window对象 是同一个对象么?

问题描述 HTML中的window对象和JavaScript中的window对象 是同一个对象么?知情的大哥大姐们,详细解释下 问题补充:Rainbow702 写道 解决方案 Window 对象表示浏览器中打开的窗口.window 是浏览器给创建的,每个载入浏览器的 HTML 文档都会成为 Document 对象浏览器打开了一个window,window里面放的是documentwindow 相当于全局变量存在于这个document中,documnet包含js,html之类,所以应该是一个对象.

DDD中的值对象如何用NHibernate进行映射

<component/>是NHibernate中一个有趣的特性,即是用来映射DDD(Data-Display-Debuger)概念形式的值类型.这是一种创建比物理数据模型具有更高粒度的对象模型的方式.  举例,   看下表中的数据:    对应的对象模型:    它们十分不同,在一个单一表中包括了所有物理数据,我们想在对象模型中调整为用两个分离的类型来映射该表.这就是<component/>的用法:  <class name="Person" table=

如何使用Fluent Nhibernate中的Automapping进行OR Mapping映射

由于在项目中使用了NHibernate来作为ORMapping构建数据访问层,那么就必须要配置Object和DataTable的映射.最早的项目中,我们使用了最传统的XML配置文件的方式编写映射关系,但是这样太麻烦,每次修改class和表时都要去修改对应的XML文件,而且还容易出错,一定有疏忽遗漏的地方,还不容易找出错误,所以在第二个项目中,我们使用了Fluent NHibernate的Mapping方式代替XML配置.使用Fluent NHibernate的最大好处是降低了出错的机会,因为Fl

NHibernate之旅(16):探索NHibernate中使用存储过程(中)

本节内容 引入 实例分析 2.创建对象 3.更新对象 结语 引入 上一篇,怎么使用MyGeneration提供的模板创建存储过程和删除对象存储过程的使用,这篇接下来介绍在NHibernate中如何使用存储过程创建对象.更新对象整个详细过程,这些全是在实际运用中积累的经验,涉及使用的错误信息,如何修改存储过程,并且比较没有使用存储过程的不同点,并非官方比较权威的资料,所以敬请参考,这篇继续,如果你还没有来及看上一篇,那赶紧去看看吧. 实例分析2.创建对象 Step1:为了比较,我们先执行Creat

NHibernate之旅(6):探索NHibernate中的事务

本节内容 事务概述 1.新建对象 [测试成功提交] [测试失败回滚] 2.删除对象 3.更新对象 4.保存更新对象 结语 上一篇我们介绍了NHibernate中的Insert, Update, Delete操作,这篇我们来看看NHibernate中的事务.你通过它可以提交或者回滚你的操作. 事务概述1.NHibernate中的事务(Transactions) 简单描述:要求ISession使用事务:做一些操作:提交或者回滚事务. 写成代码就像这样: ITransaction tx = _sess

android-addView同一个对象两次会出错

问题描述 addView同一个对象两次会出错 //首页按钮 ImageView home=new ImageView(context); home.setImageResource(R.drawable.icon_03); home.setLayoutParams(iconparams); home.setPadding(10, 10, 10, 10); addView(home); //分隔符 ImageView seprator = new ImageView(context); sepra

string-关于java中String的对象问题

问题描述 关于java中String的对象问题 String s = ""abc"";String s1 =""a""+""b""+""c"";看有关书籍介绍说这上面两句代码内存中创建了4个对象,但是也有些资料上说是只创建了一个对象,因为编译器会把字符串常量在编译过程中直接相加?还有就是 String a = ""abc&quo

[NHibernate]组件之依赖对象

目录 写在前面 文档与系列文章 组件之依赖对象 一个例子 总结 写在前面 周一至周四一直在成都出差,也一直没有更新博客了,一回到家第一件事就是扒一扒最近博客园更新的文章,然后把想看的收藏了,大概有20篇左右,包括基础的js或者jquery(快速浏览,复习基础),java方面的(主要了解实现业务的思想),asp.net webform\mvc(webform的快速浏览,mvc深入理解)等等,从昨天晚上到今天上午算是花费了7.8个小时的时间把收藏夹里面的文章看了一边. 现在就继续NHibernate