转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP(http://www.jdon.com/jive/article.jsp?forum=16&thread=6062)

转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论

kuaizxl http://www.jdon.com Apr 1, 2003 9:52 AM 回复此消息 回复

O-R Mapping
J2EE的标准是CMP Entity Bean,而实际应用中受到诟病最多的也是它。我们化了整整半年时间研究CMP2.0的开发方法,目前总算能够将代码量减少到70%,并且有希望减少到90%。我曾经很满足现有的成绩,但是当我真正地阅读了hibernate后,对CMP2.0的信心彻底动摇了。
hibernate至少比CMP2.0有以下优点:
1. 兼容性。 规范一模一样,实现各有不同,这是CMP的现状。用第三方O-R Mapping工具可以解决这个问题。
2. 保护智力投资。在了解了Orion, Weblogic, JBoss的CMP实现后,我不愿意再去学习Websphere 或者Resin的实现了。
3. 性能。
a. local v.s. remote, hibernate、JDO、Castor都是本地调用,CMP2.0虽然也有Local接口,但是Web层还是需要通过Remote接口访问EJB层的数据,序列化、网络调用、创建大量的对象,都是性能降低的原因。
b. transaction,J2EE提出了一个全新的事务模型(method-based descriptor),对程序员的开发确实是个“简化”,记得一本教程建议所有的EJB方法都用Required。但这样的结果是什么? 性能极度降低!互锁!没有办法,我们只有再去调节各个方法的Transaction属性,然后又出现 新的互锁...
新的事务模型是不成功的。它试图简化问题,却引入了更为严重的问题。各家厂商的Transaction实现也不尽相同,有的支持Optimistic Lock,有的在VM中同步Entity对象,又是兼容性的一大敌。
hibernate没有试图创造一个更新的模式,相反,它沿用了传统数据库的Transaction编程模式,在对J2EE的Transaction伤透脑筋后看到它,真是十分亲切,感觉自己确实在编程,而不是碰运气填代码了。
4. 动态Query。
Entity Bean很难实现动态Query,这是因为它基于代码自动生成技术,即最终的执行代码是在部署编译时生成的。hibernate则有根本的改变,它基于reflection机制,运行时动态Query是很自然的事。另外,hibernate几乎支持所有的SQL语法,传统数据库可以做的它就可以做。
5. 发展速度。
I have a dream, 有一天Entity Bean会变得很好。但至少目前来看,Entity Bean是一个不完善的产品,它是大公司政治斗争和妥协的产品,而且习惯性将一些问题“无限期搁置”,典型的例子就是Query(之所以不提其他问题,是因为其他都是Entity Bean的致命伤:))
形成强烈反差的是,hibernate的核心程序员只有一人,但它改进的速度确是Entity Bean无法企及的。
6. 继承和多态。
OO语言的精华在Entity Bean这里是行不通的,我曾经自我安慰将Entity Bean看做一个“内存中的数据表”,才找到了一点平衡。
但当我看到hibernate时,又开始不平衡了。

另外,CMP2.0也有一些缺点是可以弥补的。
1. 代码维护。
大量的接口文件和配置文件,开发和维护的工作量很大。
解决途径:采用xdoclet,可以自动产生众多的接口和配置文件,甚至facade, delegate等高级模式。

至少目前来看,hibernate的缺点有:
1. 代码维护
hibernate提供了自动生成mapping文件“框架”的工具,但还需要手工调节。而这类开发,能想到的最佳模式就是xdoclet的(代码+注释)的模式了。幸好,hibernate的程序员已经向xdoclet项目增加了hibernate的模块。现在需要的是等待xdoclet的下一个release。

结论:
hibernate至少从文档上超越了Entity Bean很多,我要学习hibernate。

主页:
hibernate.sourceforge.net
有愿意一起研究hibernate的大家多交流交流。

guty
guty2001@sina.com


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 1, 2003 2:52 PM
回复此消息回复
发表人: banq    发表文章: 3373 / 来  自: 上海 / 注册时间: 2002-08
对于CMP 我只能说:没有更好,只有合适。

其实你的问题主要是处理transaction上,如果手工使用JTA,你还是会伤脑筋的,因为这是个应用问题,要仔细分析你的业务对象,哪些过程是必须事务的,一般在产品的1.0都会去掉transaction,这样顺利多,等产品相对稳定成熟,这时再考虑transaction。

将entity bean想像成内存中的一张数据表,这是符合entity bean原理的,不要将太多重担压在entity bean的CMP上,对于复杂的SQL,BMP是好的选择,有种CMP-BMP模式:先使用BMP,等以后QL丰富后,再稍微改动一下就可以回到CMP,推荐你这种方式。

还有,其实大量数据库操作中有一半是查询,大量查询建议你使用DAO模式。



Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 1, 2003 2:53 PM
回复此消息回复
发表人: banq    发表文章: 3373 / 来  自: 上海 / 注册时间: 2002-08
我主要想说的是:选择框架软件最好是主流,hibernate可能很好,但是生命力有多长?如果主要开发者停止了,你的产品也就陷入停顿发展。


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 1, 2003 3:03 PM
回复此消息回复
发表人: wys1978    发表文章: 163 / 注册时间: 2002-09
我觉得JDO会是一个比较好的O/R mapping的规范, 感觉它会成为以后的趋势, :)


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 1, 2003 4:08 PM
回复此消息回复
发表人: banq    发表文章: 3373 / 来  自: 上海 / 注册时间: 2002-08
我觉得,JDO最大的缺点是性能优化很难,其实这也是EJB的问题,这个问题不解决,JDO如果只是提供使用上便利的话,想真正代替实体bean比较难。

我曾经使用过Castor,这东西用好了,很方便,但是在用的时候,摸索很长时间,不知道哪里多个空格还是少写点什么,我反复删除,重写了好几次,总算碰巧调通了,最后不知道问题在哪里,让人生畏。

而开放CMP时,由于使用Jbuilder 几乎没有什么问题,看来,越是自动化的东西,支持的开发工具就越重要。


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jul 26, 2003 11:47 AM
回复此消息回复
发表人: newjoy    发表文章: 9 / 注册时间: 2003-06
GOOD


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 29, 2003 3:01 AM
回复此消息回复
发表人: guty    发表文章: 55 / 注册时间: 2003-06
各位关注hibernate的朋友,你们好。这是我去年发在chinajavaworld上的文章,那时我的一个J2EE项目快要结束,当时特别想找一个EJB的替代技术,就发现了Hibernate,后来又发现了Rickard的AOP框架。

经过几个月的测试和基础开发,从今年初开始,我开始在项目中全面采用比较灵活的技术,其中包括用hibernate来作O-R,用webwork/OGNL来做Web页面的数据绑定,用C++和Webservices来代替Java客户程序。

目前来看,hibernate是最正确的选择,和过去的EJB开发(即使是用了xdoclet)相比,大家感觉都工作量都轻松多了。简单而强大,可以用来形容许多产品,也可以这么形容hibernate。hql语言可以做绝大多数sql能作的工作,包括outer join等高级特性。

从设计上来讲,hibernate通过对集合、继承的支持,使我们能够建立一个足够“复杂”的对象模型,而且能够“完全”覆盖数据库层,这都是它强于EJB的地方。

开源项目确实存在着banq所说的不稳定因素,但hibernate却似乎与众不同。它和eclipse是我见到的能够真正做到small iteration的开源项目,后者有IBM做后盾,前者主要是靠Gavin一年多来几乎全职地投入。目前hibernate是2.0.1版,可以说是一款非常非常非常稳定的产品。


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 2, 2003 2:32 PM
回复此消息回复
发表人: fishandfly    发表文章: 44 / 注册时间: 2003-03
castor我用过啊!除了update比较繁琐外,其他的都可以,不过他们的网站好象备分服务器坏了,所以一直没有新的版本。
我觉得castor的事务处理一般,和普通的jdbc没什么两样,本来觉得cmp的挺好的,看了搂主的文章失望不少!
不如大家都看看OFBIZ的Entity Engine吧!而且OFBIZ还提供了数据的维护工具,挺好的!

:)


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 2, 2003 3:51 PM
回复此消息回复
发表人: kuaizxl    发表文章: 5 / 注册时间: 2003-04
作为一个架构师,应该花更多时间留意最新的技术和发展的趋势,而作为一个技术负责人,应该寻找最优的解决方案,我更倾向于后者


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 3, 2003 3:29 PM
回复此消息回复
发表人: jackyz    发表文章: 35 / 注册时间: 2002-11
Great! 我正在准备一个项目,性能要求非常高。而上一个项目用 CMP O-R Mapping 的方案,其性能不能让人满意。就目前而言,我从文档以及示例程序所得到的感觉与你相同。

其次,就 EJB 而言,以 BO + session facade + CMP 的方式也是可以在 EJB 端替换为 BO + session facade + BMP + DAO(Hibernate) 的实现(这一点在 Hibernate 的文档中有提到)。或者,在性能要求非常高的情况下,还可以去掉 EJB 层,简化为 BO + (DAO)Hibernate 的方式。可以认为,只要合理的设计 DAO 接口, BO 的具体实现中可以保留实现方式上的变化。

我的项目初步计划采用 Maverick + Hibernate + JCS ,给点意见?


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Apr 7, 2003 2:27 AM
回复此消息回复
发表人: jpenguin    发表文章: 16 / 注册时间: 2003-04
I like Hibernate very much. I studied the SQL statements issued by Hibernate by turning on SQL logging of PostgreSQL. At session.flush() and then commit() time Hibernate will examine all persistent objects that have been changed (by comparing the new values with old values stored in a cache) in the session and issue SQL update statements for them. There's also XDoclet support for Hibernate now, so if you use that, you can switch to CMP if you want.


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 15, 2003 2:12 AM
回复此消息回复
发表人: dreamaster    发表文章: 11 / 注册时间: 2003-04
hibernate只是按照应该的方法实现一个持久层框架应该实现的功能,所以性能各方面都很出色,很奇怪,为什么像cmp等就做不到呢?


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 19, 2003 11:14 PM
回复此消息回复
发表人: newroc    发表文章: 3 / 注册时间: 2003-06
最近才开始注意hibernate,不知道他用的多吗,从网上的关于他的资料数量来看好像不是特别多,是我没有发现还是他比较新的缘故呢


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 20, 2003 9:49 AM
回复此消息回复
发表人: uu_snow    发表文章: 53 / 注册时间: 2002-11
如果使用hibernate,如果我在一个方法内部要同时
处理对两个DB的CUD操作和一个LDAP的操作
它好象不能保证事务的完整性吧

另外,hibernate能处理三张表以上的复杂查询操作吗?


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 21, 2003 10:52 AM
回复此消息回复
发表人: SUPERMY    发表文章: 24 / 注册时间: 2002-10
我一直以为,我已经理解了ejb,可是越深入的学习,发现很多东西还没有真正的理解。建议你深入学习一下,ejb不是像你理解的那样。我认为,ejb得使用可以使软件的开发,走上工业化、规模化的发展。


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 29, 2003 3:32 AM
回复此消息回复
发表人: guty    发表文章: 55 / 注册时间: 2003-06
也许我对ejb的理解还不是很深,对目前一些快速开发工具也不是很清楚,但根据过去的几个项目经验,我很清楚什么工作是EJB完成不了的,什么工作是纯组件模型难以封装的。

不久前一个朋友跟我说用jbuilder开发EJB非常简单了,点点鼠标就可以完成。我看他那么狂热,没有好当面泼凉水,但这里,可以顺便说说“点点鼠标”完成不了的工作:
1. 对象重构,如果要改动属性、方法、对象关系,也许界面操作就不那么轻松了;
2. 版本控制,cvs上保存哪些文件
3. 本地调试
4, 还有一点,如果对象达到数十,甚至成百上千个,如果你还认为EJB开发很轻松,我就真的很佩服你。


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 30, 2003 11:54 AM
回复此消息回复
发表人: banq    发表文章: 3373 / 来  自: 上海 / 注册时间: 2002-08
to guty:
非常感谢guty给我们提供了hibernate非常好的实践实例,我本人也非常喜欢O/R maping,他用起来真是很爽。

但是有些疑惑让我没有立即选择hibernate,当然是其稳定性和性能,当然不是否定hibernate,而这是我对待新技术的一贯方法。

在机会成熟情况下,我会实战一次hibernate,因为我一年前用过Castor,非常喜欢,现在Castor处理XML已经成为我的工具箱中对付object -->XML转换的利器,前段时间用它实现JMS Mail,将Mail转为XML message发送,真是流利。

我现在常用的数据库持久化工具是EJB CMP,为什么这样选择,正好可以回答guty的几个问题:
>1. 对象重构,如果要改动属性、方法、对象关系,也许界面操作就不那么轻松了;

因为在EJB中,首先是建立Domain Model,实体bean或数据模型或数据表结构只是Domain 模型的实现。如果改动一个基本对象,如Customer,要两部分工作:接口设计改变;剩余的是实现改变,实现有两种:数据model要改变;数据库结构改变。
以上改变无论采取什么技术如O/R mapping是都要做的。

在EJB中,数据库结构改变后,通过Jbuilder的数据库导入技术,就可以立即将改变后的数据表映射成实体bean,这个工作是容器完成的。也就是说数据库结构改变后,实际实体bean同步改变,因此EJB的实体bean并没有给我们带来附加的工作。

2.版本控制问题 因为Jbuilder整合了cvs等主流工具,也很方便,通过wincvs也可以.

3.本地调试,通过Jbuilder整合的Junit或cactus的导航设置,非常方便。

4.对象上百个后,需要有一个清晰的web和EJB控制框架,将这几百个对象以组件形式封装,比如JMSEmail.jar是专门负责异步发送Email的EJB组件,而Sequence.jar是产生序列号的EJB组件,这点可以参考petstore,Petstore实际使用了很多EJB组件,真正自己的应用实现代码很少。

这里我想多说一句,EJB分布式组件是其强大的优点,程序员编码时可以划分成组件调试编码,很方便,组合在一起发布时,由于容器的自动集群功能,发布到一台服务器后,将自动在几百台集群服务器上运行,由服务器自动实现动态负载平衡,以及单点错误恢复,这些Jboss就已经做到。

这些成熟的框架使得我一直在使用EJB。





Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 30, 2003 1:30 PM
回复此消息回复
发表人: robbin    发表文章: 585 / 注册时间: 2003-06
CMP在JBuilder里面开发确实确实很方便了,不过在JBuilder里面也只是1个表映射1个CMP,如果表非常多,并且很多表之间存在关联呢?

我遇到过数据库里面有80多张表的情况,其中绝大部分的表都会用到连接查询,如果是用CMP映射的话,必须把这些所有的关联关系都设计成CMR,那就意味着,这80多个CMP必须在一个EJB Deginer里面设计,并且只能打成一个jar包。这是非常恐怖的事情,稍微错一点点,全都完蛋了。

如果是BMP,可以在SQL里面写连接查询,如果是Hibernate,也一样。但是CMP做不到,只能用CMR,不在一个jar包里面的CMP没有办法CMR,所以80多个CMP打在一个包里面多么恐怖,光是那3个配置文件就几乎都几千行,可维护性太脆弱了。即使在JBuilder里面也是动不动报错。

后来那个项目果然失败了!

现在CMP都不会直接暴露给客户端,用Session Bean来封装Entity Bean,那么CMP的事务功能,安全性检查都没有必要,光是一个O/R Mapping的功能,就不一定非用CMP不可。用Session Bean+JDO(O/R Mapping)一样可以实现分布式。更准确的来说,甚至业务对象都可以不用Session Bean,前面加上一层Session Facade就可以分布式了。


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 30, 2003 1:43 PM
回复此消息回复
发表人: guty    发表文章: 55 / 注册时间: 2003-06
> 前面加上一层Session Facade就可以分布式了。

非常同意。

再往下做,你会发现EJB越来越成为累赘。RMI很难实现吗?JNDI真的有必要吗?Cluster有必要做得那么复杂吗?

然后你也许会自己做一个“服务器”。



Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 30, 2003 1:48 PM
回复此消息回复
发表人: guty    发表文章: 55 / 注册时间: 2003-06
>再往下做,你会发现EJB越来越成为累赘。RMI很难实现吗?JNDI真的有必要吗?Cluster有必要做得那么复杂吗?

>然后你也许会自己做一个“服务器”。

这还是使用Java应用程序客户端的情况。

如果是Web程序,或者客户端是其它语言,连RMI也没有必要,Cluster和会话机制都可以使用Web Server的,这是更为稳定和成熟的方案。


Re: 转贴:最佳J2EE方案讨论之O-R Mapping: hibernate v.s. CMP,请大家讨论 发表时间: Jun 30, 2003 3:17 PM
回复此消息回复
发表人: robbin    发表文章: 585 / 注册时间: 2003-06
guty,你好,继续讨论Hibernat的事务


一、使用ThreadLocal来保存Session和Transaction:

关于在ThreadLocal中保存transaction,你没有仔细说明Transaction何时创建,何时提交,我理解为是创建Session后,立刻创建Transaction,web层调用都结束后,提交Transaction,关闭Session。这样,可以写一个Filter来专门处理提交Transaction和关闭Session。

通过TreadLocal和Filter统一来管理Session和Thread,的确省心省力。但是这样做有一个疑问:如果业务方法只是查询数据库,没有修改操作,那么有必要启动Transaction吗?

在上面这样的管理方法中,实际上web层调用到DAO的时候,都会启动Session和Transaction,最后都会提交Transaction和关闭Session。如果只是查询数据库,没有修改的话,就没有必要启动Transaction了。

而HibernateSession.currentSession()方法不可能分辨出来后面的调用是只读,还是有修改,总是要启动一个Transaction的,而在Filter里面也总是提交Transaction的。

那么我关心的问题就是,虽然Hibernate的Transaction是JDBC Transaction,不会造成很大的系统开销,但是对数据库只读查询做commit,这种开销究竟有多大呢?是否会严重影响性能呢?

我做了一个简单的试验,用Hibernate查询MySQL数据库,反复查询500次数据库,做统计。由于只是查询数据,因此是没有必要使用Transaction的,经过比较,使用了Transaction之后,平均查询时间多了600ms,也就是说平均每次查询要多1ms的时间开销。而在我的AMD Duron700的机器上,MySQL数据库的CPU占用率从19%上升到24%。

在真实的环境中,不会出现一个线程反复多次查询数据库的情况,因此多出来的1ms的时间开销完全可以忽略不计。但是数据库的开销还是非常可观的,如果是并发线程访问,我相信数据库的开销还要增加。

所以我觉得可以把你的方案再改良一下,Filter就不用改了,检测一下tx不为空才提交。而HibernateSession.currentSession()可以给它传一个参数,比如说只查询数据,不修改数据库的时候,给它传0,光创建Session或者取Session,而不启动Transaction,不为0的时候才启动Transaction。

总体来说,使用这个办法还是相当简单易行的。


>如果是Web程序,或者客户端是其它语言,连RMI也没有必要,Cluster和会话机制都可以使用Web Server的,这是更为稳定和成熟的方案

如果Web Server和App Server不在一台物理机器上呢?你还是必须要用Session Bean。

我觉得你好像概念稍有混淆,Web Server的Cluster是Web Server的Cluster,而App Server的Cluster是App Server的Cluster,在一个大型Web应用中,完全有可能Web层进行Cluster,来分担繁重的HTTP请求,而App Server也进行Cluster,来分担繁重的业务运算,这是不搭界的两回事。

如果是单纯的Web应用,会话是在Web层实现的,使用HttpSession,而不需要使用Stateful Session Bean,但是单纯的Web Server本身不能进行HttpSession的Cluster吧?只有ServletContainer才提供的吧,比如Weblogic的HttpSession的内存复制技术。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值