回头再看看我的帖子和你对我的帖子作出的“解释”,为了攻击而做出的带有明显倾向的曲解,何至如此?

看来你还真是苦心孤诣阿!我对你佩服的五体投地!我在Jdon论坛有300多个帖子,连我自己都看不过来,你竟然火眼金睛能一一找出来,还把帖子中的错误一一指正,我只能写一个“服”字。

不过如果你再多花点心思,想必你可以找出更多明显的错误,我帖子里面的错误还不止这么一点,还多得很。Jdon论坛没有修改帖子的功能,经常是发帖子发上去了才发现敲错了字,或者发贴的时候欠考虑,等发完贴想清楚了,想改也改不了了。所以就只好让它错在那里了。

你批评Hibernate,否定Hibernate我很欢迎,技术只有越争论才越清楚,我也不希望所有的人都一股脑倾向于Hibernate,我用Entity Bean那么久了,我也不会全盘否定它,这个世界多点选择才精彩。

但是看看你的第一贴里面都说了些什么话?我看了你的第一贴,简直不敢相信自己的眼睛,我是看了三遍才确定自己没有看错的,我不知道是不是你的逻辑思维能力与众不同,但你的帖子实在是荒谬的让我无话可说了,连什么“想用,就需要学习,是缺点”这样的话也说出来了。真是“欲加之罪,何患无辞”,你无端的排斥Hibernate,连这样的理由都能找的出来,这和FUD有何区别?我也只有再次写一个“服”字,但愿你不是像我一样,发贴的时候敲错了字导致的。

其实我觉得你对Hibernate有这么深的偏见和排斥,你还何必在Hibernate上花功夫呢?看你前面的帖子,对EJB-QL掌握的很扎实,如果你觉得Entity Bean对你来说足够好了,那么还何必多此一举,自找麻烦呢?ORM的轻量级框架,有不下一百种之多,但是我碰上Hibernate以后,已经觉得足够好了,所以我不会再花功夫去学习其它的ORM了,如果当初让我先碰到了别的一样好的ORM,我也同样不会再花时间学习Hibernate了。所以我对你的劝告就是远离Hibernate。

你说我得理不饶人,可是看看你在本贴里面都贴了一些什么?本贴回了这么长,大部分帖子都是在讨论技术,如果你从头到尾看下来,应该会知道,我也一直在很认真的讨论技术问题。对Hibernate有偏见不可怕,通过我们这么多帖子的讨论,对于Hibernate存在App Server兼容性的偏见不是已经逐步被搞清楚了吗?我之所以喜欢讨论技术问题,是因为讨论的过程中,除了可以帮助别人解决问题之外,自己一些平时很少想到的地方也会因为别人的提醒而去认真思考,所以只就是相互启发的好处。

可是反过来看看你呢?除了对我的回贴耿耿于怀之外,你还提出过什么有技术含量的观点呢?至于你的第一贴,我是非彻底反驳不可的,否则的话,会有很多人因你的FUD帖而对Hibernate产生偏见和排斥,至于无法顾及到你的面子,那也是难于两全了,只好向你说抱歉了。

To Bruce:

App Class Loader
|----- EJB Class Loader
|----- Web App Class Loader


如果在App Class Loader级别配置,是全局可见的。如果打包在EJB里面,那么就不会影响到Web Application,反之亦然,如果你在WEB-INF下面放置Hibernate,也不会影响到EJB。放在EJB Class Loader或者放在Web App Class Loader级别主要就是在局部范围内有效,不影响到其它的应用。

试想,如果在一个Weblogic上面配置多个虚拟域,你使用www.bruce.com域名,开发你的网站,我使用www.fankai.com开发我的网站,那么当然不希望我们的Hibernate相互干扰,所以就可以放在 EJB Class Loader级别来配置Hibernate。

>>外,我以前试过,这两种方式好象不能共存,应该也是因为classloader的hierarchical的原因。有一点点不敢发言了 :Q<<

大概是你的配置问题吧,我试过,是可以的。


“看来你还真是苦心孤诣阿!我对你佩服的五体投地!我在Jdon论坛有300多个帖子,连我自己都看不过来,你竟然火眼金睛能一一找出来,还把帖子中的错误一一指正,我只能写一个“服”字。”


你干嘛这么歇斯底里?
我只是碰巧也回复了那个帖子,我一来这个论坛,就对你比较关注,因为你的帖子是很值得一看的,只是那个帖子让我很吃惊,应该说是吓我一跳,因为我首先怀疑我记错了,然后我去查证,的确是你错了。我只是想:高手也有犯错的地方,呵呵。

我回此贴并非攻击你,只是觉得你需要冷静一下。

“但是看看你的第一贴里面都说了些什么话?我看了你的第一贴,简直不敢相信自己的眼睛,我是看了三遍才确定自己没有看错的,我不知道是不是你的逻辑思维能力与众不同,但你的帖子实在是荒谬的让我无话可说了,连什么“想用,就需要学习,是缺点”这样的话也说出来了。真是“欲加之罪,何患无辞”,你无端的排斥Hibernate,连这样的理由都能找的出来,这和FUD有何区别?我也只有再次写一个“服”字,但愿你不是像我一样,发贴的时候敲错了字导致的。”

我想你并不是不明白我的意思,只是。。。

换种说法,大多数人已经在接触到Hibernate之前,都有了许多解决问题的方式,比如开发了程序自动生成数据表映射类,和管理这些数据表映射类进行数据库操作的类,后来发现了Hibernate,虽然想用,但却要先学会Hibernate的“表达方式”或者说“描述方式”。
另一方面,我会用Hibernate,并不意味着我会用CocoBase或者是其他的同类产品,因为他们没有标准。不像JDBC,我不用关心是Oracle还是SqlServer,我学回了JDBC接口就可以了。

事实就是这样,你有什么受不了的呢?
至于说什么“对新技术逃避,懒人”之类的不负责任的攻击性词汇,更是不知该做何评论。
在发那几句引起公愤的帖子之前,我下载了Hibernate,配了例子run了一下,还试了试它的生成xml描述文件的工具。也看了它的帮助文件,感觉上它是一个必须先了解,否则无从下手的产品。我们并不能从已有的知识很顺利的推知它的逻辑和思想。

java是跨平台的技术,有一句口号,Write Once ,Run anywhere.
作为开发者,我希望我们Learn Once ,Write anywhere .
而不是今天用Cocobase我就学cocoBase,换了个公司,别人用Hibernate我又要学Hibernate。所以,如果有ORM产品的规范该多好!如果像Tuxedo和CICS一样,各搞各的一套,受罪的是我们开发者。


进一步阐述一下EJB Class Loader的问题:

先再次强调一下,Hibernate和EJB,和App Server不存在兼容性问题,他们本来就是不相关的东西,就好像JDBC,相信没有人会认为JDBC和EJB不兼容吧,Hibernate也是一样,它只和JDBC驱动,和数据库有兼容性问题,而和EJB,和App Server完全是不搭界的两回事。凡是认为Hibernate和EJB不兼容的人,其实是都是因为对EJB学习的不到家,把责任推到Hibernate身上了。

我前面的帖子提到过Class Loader的层次,这里不重复了,总之我们先来看看Class Loader的作用范围:

BootStrap Class Loader:

load JRE\lib\rt.jar, sunrsasign.jar, charsets.jar, jce.jar, jsse.jar, plugin.jar

Ext Class Loader:

load JRE\lib\ext目录下的库文件, load JRE\classes目录下的类

App Class Loader:

load CLASSPATH变量指定路径下的类

以上的load路径都是写死在JVM的C++源代码里面的,不能改变,详细请见王森的《Java深度历险》

在一个特定的App Server上,Class Loader会继续向下继承,继承的层次会根据不同的App Server有所不同,但是肯定不会变的就是:

EJB Class Loader:

继承自App Class Loader,继承层次根据App Server有所不同,一个EJB Class Loader它的load Class的范围仅限于JAR或者EAR范围之内。

Web App Class Loader:

继承自App Class Loader,继承层次根据App Server有所不同,一个Web App Class Loader:它的load Class的范围在 WEB-INF\lib下的库文件和WEB-INF\classes目录下的class文件。

Web App Class Loader很好理解,大家毕竟用的很多,App Server上的一个Web Application会创建一个Web App Class Loader的实例去负责load class,所以如果你想让Hibernate只在这个Web Application内生效,把它放到WEB-INF\lib下去就好了。

如果你把Hibernate放到了CLASSPATH变量指定的路径下,而你在WEB-INF\lib也放了一份,那么Web App Class Loader由于load范围所限,它会首先找到WEB-INF\lib下的那份Hibernate,按照它的配置来初始化Hibernate。

如果你把Hibernate放到了CLASSPATH变量指定的路径下,但你在WEB-INF\lib什么都没有放,那么Web App Class Loader由于load范围所限,它根本什么都找不到,于是它把load Hibernate的责任交给上一级的Class Loader,这样直到App Class Loader,它找到了Hibernate,按照它的配置来初始化Hibernate。

EJB Class Loader稍微复杂一点,不那么容易理解。App Server会针对每一个EJB包文件创建一个EJB Class Loader的实例,例如:

HelloRobbin.jar
HelloBruce.jar

当你把这两个jar发布到App Server上以后,会创建两个EJB Class Loader的实例,分别去load这两个EJB包,比如说:

CLEJB_Robbin是load HelloRobbin.jar的
CLEJB_Bruce是load HelloBruce.jar的

那么CLEJB_Robbin的load范围就仅仅限于HelloRobbin.jar之内,它load不到HelloRobbin.jar之外的任何文件,当然它也load不到HelloBruce.jar。

说到这里,我相信大家应该已经明白为什么EJB规范不允许EJB有IO操作了吧?因为EJB Class Loader根本找不到jar包之外的文件!!!

如果现在你想实现HelloRobbin.jar和HelloBruce.jar的互相调用,那么该怎么办?他们使用了不同的EJB Class Loader,相互之间是找不到对方的。解决办法就是使用EAR。

现在假设HelloRobbin.jar和HelloBruce.jar都使用了Hibernate,看看该怎么打包和发布:

HelloEJB.ear
|------ HelloRobbin.jar
|------ HelloBruce.jar
|------ Hibernate2.jar
|------ pojo.jar (定义所有的持久对象和hbm文件的jar包)
|------ cglib-asm.jar
|------ commons-beanutils.jar
|------ commons-collections.jar
|------ commons-lang.jar
|------ commons-logging.jar
|------ dom4j.jar
|------ odmg.jar
|------ log4j.jar
|------ jcs.jar
|------ hibernate.properties
|------ log4j.properties
|------ cache.ccf
|------ META-INF\application.xml (J2EE规范的要求,定义EAR包里面包括了哪几个EJB)

除此之外,按照EJB规范要求,HelloRobbin.jar和HelloBruce.jar还必须指出调用jar包之外的类库的名称,这需要在jar包的manifest文件中定义:

HelloRobbin.jar
|------ META-INF\MANIFEST.MF

MANIFEST.MF中必须包括如下一行:

Class-Path: log4j.jar hibernate2.jar cglib-asm.jar commons-beanutils.jar commons-collections.jar commons-lang.jar
commons-logging.jar dom4j.jar jcs.jar odmg.jar jcs.jar pojo.jar

这样就OK了,当把HelloEJB.ear发布到App Server上以后,App Server创建一个EJB Class Loader实例load EAR包里面的EJB,再根据EJB的jar包里面的MANIFEST.MF指出的Class-Path去寻找相应的jar包之外的类库。

所以一个EAR包有点类似一个Web Application,EJB Class Loader的load范围也就是EAR范围之内,它load不到EAR之外的文件。除非把Hibernate定义到CLASSPATH指定的路径下,在这种情况下,EJB Class Loader找不到Hibernate,只能交给上一级的Class Loader,最后由App Class Loader找到Hibernate,进行初始化。


没有写完,继续说...

由于EAR这样load Class规则,假设Robbin和Bruce都在同一个Weblogic上运行自己的网站,而我们都不希望自己的程序里面的Hibernate配置被对方的搞乱掉,那么我们就可以这样来做:

Robbin's Website:

Robbin.ear
|-------- robbin.war (把Web Application打包)
|-------- robbin.jar (把开发的EJB打包)
|-------- Hibernate2.jar
..........................
|-------- META-INF\application.xml


Bruce's Website:

Bruce.ear
|-------- bruce.war (把Web Application打包)
|-------- bruce.jar (把开发的EJB打包)
|-------- Hibernate2.jar
..........................
|-------- META-INF\application.xml

这样在同一个App Server上运行,就可以互相不干扰。

To: mellon

我不觉得我犯了常识性错误有什么好难为情的,不过大部分情况下,都是因为敲错贴上去又不能修改的缘故。即使是我确实把知识理解错了,被别人纠出来,那也很好阿,可以帮我纠正错误的观念。那个帖子我自己都不记得我贴过了,还能被你找出来,我确实很惊讶。

你的第一贴,看完了之后,我唯一的感想就是连从技术角度去反驳的兴趣都丧失了,我看到的是一个对对象持久层无知,但是疯狂攻击Hibernate的帖子。请原谅我用“疯狂”这个字眼,但是这是我真实的感想。

好了,结束非技术的攻击,开始技术争论,现在认真回复你的贴子:

看来你对Hibernate的攻击主要源自于你认为Hibernate不是一个规范,Hibernate的经验不能用在其它地方,学习成本高。

你如果认真看看我前面回复yung的第一贴,和之后接下去的一个总结帖子,应该多次看到我在强调的一点:学习Hibernate主要不是在学习Hibernat怎么配置,用工具怎么生成hbm文件,如果你把重点放在这里,基本上等于白学了Hibernate。Hibernate的精华在于无与伦比的灵巧的对象持久层设计,这些持久层设计经验不会因为你不用Hibernate而丧失掉,我自己学习Hibernate,已经明显感觉到对持久层设计能力已经长了很多经验值了,这些经验甚至不光可以用在Java上,用在.net上也是一样。所以Hibernate配置的学习,我只是简单看看,用的时候知道到那里去查就行了,一堆复杂的生成工具我根本就看都不去看,这样算下来,掌握Hibernate的配置,可以用Hibernate来替代JDBC写程序,不过花上3天时间就足够了。我想3天时间对你来说不算很奢侈的学习代价吧。

为什么我这么强调学习Hibernate的对象持久层设计理念呢?那就看你的理想是想一辈子做一个程序员呢?还是想向更高的方向发展呢?从纯做技术的角度来说,职业发展的最高点是“系统架构师”,Bill Gates不是还叫做微软的首席系统架构师吗?System Architect职位需要的是你的学习和领悟能力,如果你不能把学习Hibernate得到的设计经验运用到其它地方,那么你是失败的,也没有资格做System Architect。

不管JDO也好,Hibernate也好,TopLink也好,CocoBase也好,还是Castor,还是什么Torque,OJB,软件的使用和配置方法可以各异,但本质上都是ORM,都是对JDBC的对象持久层封装,所以万变不离其宗,如果你完整的学习和掌握Hibernate花了1个月的时间,那么你再学习OJB的时间不应该超过1个星期,因为你已经把对象持久层设计都了然于胸了,你需要的只是熟悉一下OJB的API和配置罢了,至于怎么运用OJB进行持久层的开发你早就已经熟悉了。

所以当你掌握了两种以上的ORM,你应该能够不拘于使用的ORM软件的限制,设计出适合于你的项目的持久层来,这才是System Architect的水准。用金庸小说来打个比方来说吧,张无忌学太极剑,只记剑意,不记剑招,这才是真正的高手,而低手就只会去学习剑招,而不去领会剑招背后蕴含的剑意,所以一辈子都是低手,永远不能真正学会太极剑。所以周颠看到张三丰第二次演示太极剑,招式完全不同就以为是另一套东西,其实本质上都一样。学习Hibernate也不要舍本逐末的去学各种五花八门的工具,重点掌握它的对象持久层设计理念。

ORM产品的规范也不是没有,JDO就是一个ORM产品规范,但是遗憾的是JDO太令我失望了,前面一个帖子我详细谈了JDO的缺陷。我第一个关注的ORM就是JDO,如果JDO能够让我满意,我也根本不去学Hibernate了。标准这个东西是双刃剑,在某种程度上,标准桎梏了技术的发展。EJB今天就是一个灾难,EJB够标准了吧,你敢拍胸脯说任意主流App Server上的EJB都可以移植吗?单单你在Weblogic和Websphere上移植就够你受的了。如果你不是经常跳槽,或者你即使经常跳槽,但是你在技术上有足够的影响力,那为什么又不能影响公司来使用Hibernate呢?这难道很困难吗?如果你真的那么在乎标准,你可以使用CMP或者JDO阿,也没有人来强迫你使用Hibernate,你何必一面痛苦的学习Hibernate,一面否定它呢?反过来说,Hibernate既然不是标准,为什么那么受欢迎呢?这反衬了标准的失败。一个标准能不能成功有一定的历史原因,JDBC的成功就是如此,有一个好的历史机遇,但是在ORM领域标准是失败的,你就是强求也没有用。至于你的第一贴,我就不回了,那让我觉得我在科普。

提到学习方法,想多说两句:

Java本身是一种设计的非常简单,非常精巧的语言,所以Java背后的原理也很简单,归结起来就是两点:

1、JVM的内存管理

理解了这一点,所有和对象相关的问题统统都能解决

2、JVM Class Loader

理解了这一点,所有和Java相关的配置问题,包括各种App Server的配置,应用的发布问题统统都能解决

就像张无忌学太极剑,本质就是一圈一圈的画圆,你要是懂得了太极剑的本质,那么太极剑就那么一招而已,本身是很容易学的,只是难度在于你要能够举一反三,化一式剑意为无穷无尽的剑招,这就需要一点悟性和不断的实践了;反过来说,如果学剑不学本质,光学剑招,你就是学会了1万招,碰到了第1万零1招,还是不会招架,败下阵来。

技术世界本来就是丰富多彩,企图统一标准,实际上也做不到,但是世界本质其实并不复杂。学习技术,特别是某种具体的软件工具的时候,应该学会迅速把握事物的本质,不要过多搅缠细节。软件工具应该为我所用,而不是我被工具所驾驭。当你具备了对整个J2EE架构的设计和实施的能力,你还会被具体的工具束缚吗?哪种工具适合你的架构,你就用什么,哪种不适合你,你就抛弃它,软件皆臣服于你的脚下,而不是你被什么软件牵着鼻子走,到了这种程度,你难道还害怕学习什么新的软件?

我自己也在一直朝着这个方向努力,在我心中,设计软件,架构是第一位的,采用什么技术要为架构服务。如果我发现什么技术对我的架构来说很重要,那么我会花时间去学习,去钻研,就像我花时间去钻研ORM一样,如果我觉得什么技术对我的架构来说没有用,即使技术再火爆,我也不去碰它。

总之要学会抓住本质,驾驭技术,而不是被技术所驾驭。当你掌握了本质原理,其实学什么都很快,毕竟都是相通的,我先看JDO,后看Hibernate,其实两者就很类似,所以学得很快,以后如果有工作需要,要我学习别的ORM,那我也不会觉得有什么困难的,一样手到拿来。

更有说服力的是Unix类的操作系统,那就更相似了,只要抓住了Unix最本质的几点,例如shell命令和编程,文件系统结构和配置,系统启动原理和过程,所有的Unix都是无师自通的。我自己会用Linux,FreeBSD,SCO Unix, Solaris,HP-UX 和 AIX等6种Unix,更体会到一通百通的道理。

拿刚出了光明顶密道的张无忌来说吧,(我很喜欢张无忌这个角色),他也没有练过什么武功,但是他已经把天下武学之本质:九阳神功 + 乾坤大挪移 学会了,所以不管什么功夫,他都是看一遍就会,马上为我所用,看了空性用了一遍龙爪手,就会用龙爪手来破对方;和昆仑派打了一架,就会用昆仑剑法和灭绝师太过招;七伤拳更是无师自通;太极拳也是看一遍就会。

总之,学习方法还是很重要,别被五花八门的技术给搞不清学习方向了。

掌握新技术是好,不过评论技术还是要客观一些,!!

robbin 看样子,很理解哦!!!



感谢Robin详尽的说明.辛苦啦!

靠,我的头像怎么在你那儿了?

版权所有,违者必究

哈哈,有意思阿!要不是后面guty的抗议,我还真的把上面两个帖子当成guty发的了,我就注意那个刘备的头像了,没有注意看ID。