NHiberate PK Borland Eco ----的若干疑问
最近因为工作需要,研究在项目中实践NHibernate的可能性,但经研究之后,发现这个在Java世界里如日中天的ORM工具并没有想象中那么好,以下是我的一些总结,顺便有一些问题,请精通Hibernate的同学帮忙解答。1.关于POJO的定义。
Plain Old Java Object
这种平凡的对象充当实体定义有什么好处呢?虽然从定义上看起来是Plain了,但是运行的时候实际上又并不Plain,因为接入了一大堆和ISession相关的接口,用于延迟加载或其它目的。
我觉得Borland的Eco做得非常好,实体不能脱离容器(EcoSpace)而存在。这样就不会有Hibernate关于实体生命周期的处理(transient,detached,persist三种状态切换的烦恼,以及延迟加载时是否挂在ISession的烦恼)。
Hibernate是反EJB诞生的,用POJO取代实体Bean,但这明显是纠枉过正。Eco同样是轻量级,只不过把容器接口(EcoSpace)直接从中间服务器拉到应用层面上而已。
也许有人认为POJO式的定义,使得POJO可以直接作为DTO使用。但事实上,如果是Web UI层直接使用,根本不需要DTO。如果在SOA中使用,也许通过转成表格行服务更有效些。
2.HQL PK OCL
Hibernate提供了HQL语言以供对象查询,但HQL不过是SQL的变种,这种查询仍然是纯粹的基于持久化数据库的。
OCL则是一种纯粹的内存对象查询,它和SQL截然不同,也并非大家想象中的OCL会转成SQL去操作。(当然,Borland Eco中有一个PsQuery,要以将OCL转成SQL对数据库查询,但只是一个相当简陋的子集)。
现在的问题是:ORM的真正目的并不是让大家使用方便,而是将业务逻辑的运算从数据库移到内存中,HQL并不能完成这样的使命。如果采用面向表格的模式,如Net中的DataSet,可以有非常强的本地内存化操作。在Eco中,有Ocl可以对EcoSpace中的任何对象进行操作。HQL呢?----它终究不过是DAL层的东东。
3、但是Hibernate为什么能够在Java里流行起来,也许只是因为在Java的Web框架中,几乎任何操作都被简化成了单实体操作,而Hibernate基本上还是可以完成单实体操作的任务的。
4、现在我碰到了一个问题是:
我在Asp.net中使用NHibernate,当易做图作一个单据,如订单的单据,它有一些主表的信息(单据头),也有子表的信息。
如果在Eco中,我要处理的很简单,不管是新增一张单据,还修改一张单据,我只需要记住这个订单的Key就行了(如果是新增的订单,EcoSpace会生成一个临时Key),然后每次重新进入这个页面时,通过Key从EcoSpace中取得有史以来对这个Key的订单的任何操作遗留下来的状态。
然后有一个保存按扭,啪啦一下就把这张单据所有的更新持久化到数据库中去了。
一点烦恼都没有啊,EcoSpace处理一切,在Web层中我只有保存Key的信息就行了。
可是,当我在NHibernate中处理相似的问题时,我傻眼了。
a.由于是POCO,NHibernate并未对新增的对象(Transient)和容器中的对象(Persist)进行统一的健值处理,所以同一张单据,你新增的时候,要自己缓存一个对象,而更新的时候,你又要记下键值从ISession中获取。
这是第一个不爽。
b.好,将就些吧,这个我忍了,为了整个单据在新增及更新上保持一致,我准备将整个订单对象(SaleOrder)在Web中缓存起来,可是,在提交的时候,我又晕了,跟踪SQL发现,当我持久化这个对象时,我发现NHibernate竟然把整个SaleOrder的任何数据都全部提交一遍,也就是说,在跨ISession操作时(因为是Web应用,每次Request都会开关ISession),对象的脏检查机制失效了。
现在我要问Hibernate高手的问题就是:如何在跨ISession操作时,一个被Detached的对象的修改状态,如何在重新Tached时,能被感知到,这样持久化时只持久被更新的部分?
c.就前面这几个问题,已经严重不爽了,更不说NHiberate没有象Eco一样提供强大的OCL操作,对于复杂的业务逻辑处理,只有原始的操作IList进行了。
--------------------编程问答-------------------- 沙发,友情UP
--------------------编程问答-------------------- 有点难度哦
补充:.NET技术 , .NET技术前瞻