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

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

对于CMP 我只能说:没有更好,只有合适。

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

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

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


我主要想说的是:选择框架软件最好是主流,hibernate可能很好,但是生命力有多长?如果主要开发者停止了,你的产品也就陷入停顿发展。

我觉得JDO会是一个比较好的O/R mapping的规范, 感觉它会成为以后的趋势, :)

我觉得,JDO最大的缺点是性能优化很难,其实这也是EJB的问题,这个问题不解决,JDO如果只是提供使用上便利的话,想真正代替实体bean比较难。

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

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

castor我用过啊!除了update比较繁琐外,其他的都可以,不过他们的网站好象备分服务器坏了,所以一直没有新的版本。
我觉得castor的事务处理一般,和普通的jdbc没什么两样,本来觉得cmp的挺好的,看了搂主的文章失望不少!
不如大家都看看OFBIZ的Entity Engine吧!而且OFBIZ还提供了数据的维护工具,挺好的!

:)

作为一个架构师,应该花更多时间留意最新的技术和发展的趋势,而作为一个技术负责人,应该寻找最优的解决方案,我更倾向于后者

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 ,给点意见?

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.

hibernate只是按照应该的方法实现一个持久层框架应该实现的功能,所以性能各方面都很出色,很奇怪,为什么像cmp等就做不到呢?

最近才开始注意hibernate,不知道他用的多吗,从网上的关于他的资料数量来看好像不是特别多,是我没有发现还是他比较新的缘故呢

如果使用hibernate,如果我在一个方法内部要同时
处理对两个DB的CUD操作和一个LDAP的操作
它好象不能保证事务的完整性吧

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

我一直以为,我已经理解了ejb,可是越深入的学习,发现很多东西还没有真正的理解。建议你深入学习一下,ejb不是像你理解的那样。我认为,ejb得使用可以使软件的开发,走上工业化、规模化的发展。

各位关注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版,可以说是一款非常非常非常稳定的产品。

也许我对ejb的理解还不是很深,对目前一些快速开发工具也不是很清楚,但根据过去的几个项目经验,我很清楚什么工作是EJB完成不了的,什么工作是纯组件模型难以封装的。

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