﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Tin's Blog-随笔分类-Hibernate相关</title><link>http://www.blogjava.net/iamtin/category/7427.html</link><description>You are coming a long way, baby~Thinking, feeling, memory...</description><language>zh-cn</language><lastBuildDate>Mon, 17 Sep 2007 20:09:17 GMT</lastBuildDate><pubDate>Mon, 17 Sep 2007 20:09:17 GMT</pubDate><ttl>60</ttl><item><title>大型Java Web项目的架构和部署调优问题</title><link>http://www.blogjava.net/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Mon, 17 Sep 2007 14:48:00 GMT</pubDate><guid>http://www.blogjava.net/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.html</guid><wfw:comment>http://www.blogjava.net/iamtin/comments/146003.html</wfw:comment><comments>http://www.blogjava.net/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iamtin/comments/commentRss/146003.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iamtin/services/trackbacks/146003.html</trackback:ping><description><![CDATA[<img height="44" alt="" src="http://www.infoq.com/styles/cn/i/logo.gif" width="140" border="0" /> 本文已经发表于InfoQ中文站，（<a href="http://www.infoq.com/cn/news/2007/09/java_web_architecture_turnning">大型Java Web项目的架构和部署问题</a>）<br />
<style>
blockquote {background:#eee;font-size:12px;}
</style>
<p>一位ID是jackson1225的网友在javaeye询问了<a title="一个大型Web系统的架构和部署选型问题" href="http://www.javaeye.com/topic/117564?page=1" target="_blank">一个大型Web系统的架构和部署选型问题</a>，希望能提高现有的基于Java的Web应用的服务能力。由于架构模式和部署调优一直是Java社区的热门话题，这个问题引发了很多热心网友的讨论，其中一些意见对其它大型Web项目也有很好的指导意义。在讨论之初jackson1225这样描述了当前的应用的架构和部署方案：</p>
<blockquote>
<p>目前系统架构如下:</p>
<ol>
    <li>web层采用struts+tomcat实现，整个系统采用20多台web服务器，其负载均衡采用硬件F5来实现；
    <li>中间层采用无状态会话Bean+DAO+helper类来实现，共3台weblogic服务器，部署有多个EJB，其负载均衡也采用F5来实现；
    <li>数据库层的操作是自己写的通用类实现的，两台ORACLE数据库服务器，分别存放用户信息和业务数据；一台SQL SERVER数据库，是第三方的业务数据信息； </li>
</ol>
<p>web层调用EJB远程接口来访问中间件层。web层首先通过一个XML配置文件中配置的EJB接口信息来调用相应的EJB远程接口；</p>
<p>该系统中一次操作涉及到两个ORACLE库以及一个SQL SERVER库的访问和操作，即有三个数据库连接，在一个事务中完成。</p>
</blockquote>
<p>这样的架构其实很多公司都在使用，因为Struts和Tomcat分别是最流行的Java Web MVC框架和Servlet容器，而F5公司的负载均衡是横向扩展常见的解决方案（例如配置session sticky方案）。由于这个系统中有跨数据源的事务，所以使用Weblogic Server EJB容器和支持两阶段提交的数据库驱动就可以保证跨数据源的事物完整性（当然，容器管理的分布式事务并非是唯一和最优的解决方案）。</p>
<p>但是随着Rod Johnson重量级的著作《J2EE Development without EJB》和其中的Spring框架的流行，轻量级框架和轻量级容器的概念已经深入人心。所以对于jackson1225提出的这个场景，大多数网友都提出了置疑，认为这个系统滥用了技术，完全是在浪费钱。网友们大都认为SLSB（无状态会话Bean）完全没有必要出现在这个场景中，认为SLSB通过远程接口访问本地资源会有很大的性能开销，这种观点也是Rod johnson在without EJB中批判EJB 2.x中的一大反模式。</p>
<p>由于JavaEE是一个以模式见长的解决方案，模式和架构在JavaEE中占有很重要的地位，所以很多业内专家也都警惕&#8220;反模式（Anti-patterns）&#8221;的出现。对于上面所述的方案是否是反模式，jackson1225马上站出来申辩：</p>
<blockquote>
<p>我们项目就是把EJB作为一个Facade，只是提供给WEB层调用的远程接口，而且只用了无状态会话Bean，所以性能上还可以的。</p>
</blockquote>
<p>这个解释很快得到了一些网友的认可，但是大家很快意识到架构的好坏决定于是否能够满足用户的需求，davexin（可能是jackson1225的同事）描述了这个系统的用户和并发情况：</p>
<blockquote>
<p>现在有用户4000万，马上要和另一个公司的会员系统合并，加起来一共有9000万用户。数据量单表中有一亿条以上的数据。这是基本的情况，其实我觉得现在的架构还是可以的，现在支持的并发大概5000并发用户左右，接下来会进行系统改造，目标支持1万个并发用户。</p>
</blockquote>
<p>具体的并发量公布后又有网友置疑这个数据，认为这个系统的Servlet容器支持的并发数太小，怀疑是否配置不够优化。davexin又补充了该项目的服务器配置：</p>
<blockquote>
<p>系统前端tomcat都是用的刀片，配置在2G内存，cpu大概在2.0G，每台机器也就支持250-400个并发，再多的话，就会相应时间非常的常，超过20秒，失去了意义 ，所以我们才得出这样的结论的。</p>
</blockquote>
<p>一位ID是cauherk的网友提出了比较中肯的意见，他没有从Web容器单纯的并发支持能力上提出改进方案，而是提出了对于类似的应用的<a title="一些通用的改进提示" href="http://www.javaeye.com/topic/117564?page=4#368432" target="_blank">一些通用的改进提示</a>，这里摘要一下：</p>
<blockquote>
<ol>
    <li>数据库压力问题
    <p>可以按照业务、区域等等特性对数据库进行配置，可以考虑分库、使用rac、分区、分表等等策略，确保数据库能正常的进行交易。</p>
    <li>事务问题
    <p>要在两个数据库中操作，那么必须考虑到分布式事务。你应该仔细的设计你的系统，来避免使用分布式事务，以避免分布式事务带来更多的数据库压力和其它问题。推荐你采用延迟提交的策略(并不保证数据的完整)，来避免分布式事务的问题，毕竟commit失败的几率很低。</p>
    <li>web的优化
    <p>将静态、图片独立使用不同的服务器，对于常态的静态文件，采用E-TAG或者客户端缓存， google很多就是这样干的。对于热点的功能，考虑使用完全装载到内存，保证绝对的响应速度，对于需要频繁访问的热点数据，采用集中缓存(多个可以采用负载均衡)，减轻数据库的压力。</p>
    <p>对于几乎除二进制文件，都应该在L4上配置基于硬件的压缩方案，减少网络的流量。提高用户使用的感知。</p>
    <li>网络问题
    <p>可以考虑采用镜像、多路网络接入、基于DNS的负载均衡。如果有足够的投资，可以采用CDN(内容分发网)，减轻你的服务器压力。</p>
    </li>
</ol>
</blockquote>
<p>cauherk的这个分析比较到位，其中ETags的方案是最近的一个热点，InfoQ的&#8220;<a title="使用ETags减少Web应用带宽和负载" href="http://www.infoq.com/cn/articles/etags" target="_blank">使用ETags减少Web应用带宽和负载</a>&#8221;里面对这种方案有很详细的介绍。一般以数据库为中心的Web应用的性能瓶颈都在数据库上，所以cauherk把数据库和事务问题放到了前两位来讨论。但是davexin解释在所讨论的这个项目中数据库并非瓶颈：</p>
<blockquote>
<p>我们的压力不在数据库层，在web层和F5。 当高峰的时候 ，F5也被点死了，就是每秒点击超过30万，web动态部分根本承受不了。根据我们程序记录，20台web最多承受5000个并发，如果再多，tomcat就不响应了。就像死了一样。</p>
</blockquote>
<p>这个回复让接下来的讨论都集中于Web容器的性能优化，但是<a title="JavaEye站长robbin发表了自己的意见" href="http://www.javaeye.com/topic/117564?page=5#369868" target="_blank">JavaEye站长robbin发表了自己的意见</a>，将话题引回了这个项目的架构本身：</p>
<blockquote>
<p><strong>performance tuning最重要的就是定位瓶颈在哪里，以及瓶颈是怎么产生的。</strong></p>
<p><strong>我的推测是瓶颈还是出在EJB远程方法调用上！</strong></p>
<p>tomcat上面的java应用要通过EJB远程方法调用，来访问weblogic上面的无状态SessionBean，这样的远程方法调用一般都在100ms~500ms级别，或者更多。而如果没有远程方法调用，即使大量采用spring的动态反射，一次完整的web请求处理在本地JVM内部的完成时间一般也不过20ms而已。一次web请求需要过长的执行时间，就会导致servlet线程被占用更多的时间，从而无法及时响应更多的后续请求。</p>
<p>如果这个推测是成立的话，那么我的建议就是既然你没有用到分布式事务，那么就干脆去掉EJB。weblogic也可以全部撤掉，业务层使用spring取代EJB，不要搞分布式架构，在每个tomcat实例上面部署一个完整的分层结构。</p>
<p>另外在高并发情况下，apache处理静态资源也很耗内存和CPU，可以考虑用轻量级web server如lighttpd/litespeed/nginx取代之。</p>
</blockquote>
<p>robbin的推断得到了网友们的支持，davexin也认同robbin的看法，但是他解释说<a title="公司认为放弃SLSB存在风险" href="http://www.javaeye.com/topic/117564?page=6#370089" target="_blank">公司认为放弃SLSB存在风险</a>，所以公司倾向于通过将Tomcat替换为Weblogic Server 10来提升系统的用户支撑能力。<a title="robbin则马上批评了这种做法" href="http://www.javaeye.com/topic/117564?page=6#370107" target="_blank">robbin则马上批评了这种做法</a>：</p>
<blockquote>
<p>坦白说我还从来没有听说过大规模互联网应用使用EJB的先例。为什么大规模互联网应用不能用EJB，其实就是因为EJB性能太差，用了EJB几乎必然出现性能障碍。</p>
<p>web容器的性能说到底无非就是Servlet线程调度能力而已，Tomcat不像WebLogic那样附加n多管理功能，跑得快很正常。对比测试一下WebLogic的数据库连接池和C3P0连接池的性能也会发现类似的结论，C3P0可要比WebLogic的连接池快好几倍了。这不是说WebLogic性能不好，只不过weblogic要实现更多的功能，所以在单一的速度方面就会牺牲很多东西。</p>
<p>以我的经验来判断，使用tomcat5.5以上的版本，配置apr支持，进行必要的tuning，使用BEA JRockit JVM的话，在你们目前的刀片上面，支撑500个并发完全是可以做到的。结合你们目前20个刀片的硬件，那么达到1万并发是没问题的。当然这样做的前提是必须扔掉EJB，并置web层和业务层在同一个JVM内部。</p>
</blockquote>
<p>接下来robbin还针对davexin对话题中的应用分别在tomcat和weblogic上的测试数据进行了分析：</p>
<blockquote>引用：
<blockquote>
<p>2。1台weblogic10 Express（相当于1台tomcat，用于发布jsp应用）加1台weblogic10（发布ejb应用），能支持1000个并发用户......<br />
......<br />
4。1台tomcat4.1加1台weblogic8，只能支持350个并发用户，tomcat就连结超时，说明此种结构瓶颈在tomcat。 </p>
</blockquote>
<p>这说明瓶颈还不在EJB远程调用上，但是问题已经逐渐清楚了。为什么weblogic充当web容器发起远程EJB调用的时候可以支撑1000个并发，但是tomcat只能到350个？只有两个可能的原因：</p>
<p>
<ol>
    <li>你的tomcat没有配置好，严重影响了性能表现
    <li>tomcat和weblogic之间的接口出了问题 </li>
</ol>
<p>&nbsp;</p>
</blockquote>
<p>接着springside项目发起者江南白衣也提出了一个总体的优化指导：</p>
<blockquote>
<p>1.基础配置优化</p>
<p>tomcat 6？ tomcat参数调优?<br />
JRockit JVM? JVM参数调优？<br />
Apache+Squid 处理静态内容？ </p>
<p>2.业务层优化</p>
<p>部分功能本地化，而不调remote session bean?<br />
异步提交操作,JMS？<br />
cache热点数据？ </p>
<p>3.展示层优化</p>
<p>动态页面发布为静态页面？<br />
Cache部分动态页面内容？ </p>
</blockquote>
<p>davexin在调整了Tomcat配置后应验了robbin对tomcat配置问题的质疑，davexin这样描述经过配置优化以后的测试结果：</p>
<blockquote>
<p>经过测试，并发人数是可以达到像robbin所说的一样，能够在600人左右，如果压到并发700人，就有15%左右的失败，虽然在调整上面参数之后，并发人数上去了，但是在同样的时间内所完成的事务数量下降了10%左右，并且响应时间延迟了1秒左右，但从整体上来说，牺牲一点事务吞吐量和响应时间，并发人数能够提高500，觉得还是值得的。</p>
</blockquote>
<p>至此这个话题有了一个比较好的结果。这个话题并非完全针对一个具体的项目才有意义，更重要的是在分析和讨论问题的过程中网友们解决问题的思路，尤其是cauherk、robbin、江南白衣等几位网友提出的意见可以让广大Java Web项目开发者了解到中、大型项目所需要考虑的架构和部署所需要考虑的关键问题，也消除了很多人对轻量Servlet容器与EJB容器性能的一些误解。</p>
<p>在讨论中还有一些小插曲，如davexin和江南白衣讨论了<a title="JRocket的实时（Realtime）版本是否可以提升Servlet容器的相应能力" href="http://www.javaeye.com/topic/117564?page=8#371197" target="_blank">JRocket的实时（Realtime）版本是否可以提升Servlet容器的相应能力</a>，答案是不可以。还有ID为mfc42d的网友从Servlet容器的并发支持能力引申到了<a title="Java的线程调度能力和NIO对Servelet容器的意义" href="http://www.javaeye.com/topic/117564?page=8#377459" target="_blank">Java的线程调度能力和NIO对Servelet容器的意义</a>，他推荐了自己的两篇不错的blog&#8220;<a title="java的线程实现" href="http://blogger.org.cn/blog/more.asp?name=hongrui&amp;id=25175" target="_blank">java的线程实现</a>&#8221;和&#8220;<a title="java进程使用的最大内存的数值" href="http://blogger.org.cn/blog/more.asp?name=hongrui&amp;id=23973" target="_blank">java进程使用的最大内存的数值</a>&#8221;，blog文章里面从JVM源码级别分析了Java的线程支持能力，面临JVM性能调优问题的网友可以认真阅读一下。</p>
<img src ="http://www.blogjava.net/iamtin/aggbug/146003.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iamtin/" target="_blank">Tin</a> 2007-09-17 22:48 <a href="http://www.blogjava.net/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TSS上面关于hibernate的get和load方法区别的讨论</title><link>http://www.blogjava.net/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Fri, 26 Jan 2007 06:27:00 GMT</pubDate><guid>http://www.blogjava.net/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html</guid><wfw:comment>http://www.blogjava.net/iamtin/comments/96146.html</wfw:comment><comments>http://www.blogjava.net/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/iamtin/comments/commentRss/96146.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iamtin/services/trackbacks/96146.html</trackback:ping><description><![CDATA[
		<p>TSS上面Ganesh同志的文章内容是非常有益的，讨论了session的这两个api的区别。get是每次都会从数据库取数据以保证数据的可靠。而load则会返回一个proxy，相当于一个存根，访问的时候从当前session或者hibernate二级缓存中查找，如果找不到则从数据库中Lazy Load一下。从Hibernate的复杂性上来说，这个概念应该算比较容易理解的，而且这种存在也是非常合理的。顺便里面还补充了一下JPA里面也有类似的getReference方法，行为类似load。看完文章你会开始注意这个细节。<br />可是，这个细节的下面却引起了n多人的讨论，讨论的核心就是Hibernate是不是有太多细节了？<br />很多人说这样不是OO的，很多人说Hibernate的细节造成它复杂，有人说Hibernate影响了他们的工作效率，等等，反正反对者站出来很多。我想这是可喜的。<br />说明在Java的Killer-APP组合Spring+Hibernate后面还是有很多持怀疑态度的人的，我们随时都需要提问题的大脑！<br />所以，我们也思考一下吧：<br />1、你一定要尽量的不断地熟悉你所使用的技术，可以是Hibernate也可以是JDBC，时刻保持对相关知识的饥渴。这样减少因为你的无知造成的失误。<br />2、思考别人的批评，或者说ORM不好，或者说这种那种ORM不好，你都要听着，然后思考，然后坚持你思考的结果，直到下一次思考。这个过程最好保持一定的技术偏执，因为没有性格的程序员不是好程序员。<br />3、放眼各种技术，了解相似技术，这样你不会在城头更换大王旗的时候失业:D。现在我们可以回头看看JDBC Dataset和JPA，向上向下都要看齐嘛。了解了相似技术更有助于你的思考。<br />4、知道你在讨论什么，知道背景。你需要知道Hibernate主要在Java or JavaEE中使用，当然有Hibernate.net，但是它不怎么火。还有，Hibernate的基础还是SQL和DBMS，你需要仔细了解这两种东西。<br />5、悟道。</p>
		<p>Ganesh的原文：<br />Hibernate - Difference between session's get() and load()<br /><a href="http://gmarwaha.blogspot.com/2007/01/hibernate-difference-between-sessions.html">http://gmarwaha.blogspot.com/2007/01/hibernate-difference-between-sessions.html</a><br />TSS上的讨论：<br />Difference between Hibernate's get() and load()?<br /><a href="http://www.theserverside.com/news/thread.tss?thread_id=43887">http://www.theserverside.com/news/thread.tss?thread_id=43887</a><br /></p>
		<p>我以前翻译的Hibernate的session的javadoc，当时好像从字面上没有什么大的区别，配合这个帖子，要重新想一想:D<br /><a href="/iamtin/archive/2006/03/06/33910.html">http://www.blogjava.net/iamtin/archive/2006/03/06/33910.html</a><br /><br />BTW：因为做手术在家休养，所以才有时间发发牢骚:D</p>
<img src ="http://www.blogjava.net/iamtin/aggbug/96146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iamtin/" target="_blank">Tin</a> 2007-01-26 14:27 <a href="http://www.blogjava.net/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>手动为HibernateDAO里面的DetachedCriteria的Projection擦屁股</title><link>http://www.blogjava.net/iamtin/archive/2006/06/06/50702.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Tue, 06 Jun 2006 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/iamtin/archive/2006/06/06/50702.html</guid><wfw:comment>http://www.blogjava.net/iamtin/comments/50702.html</wfw:comment><comments>http://www.blogjava.net/iamtin/archive/2006/06/06/50702.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/iamtin/comments/commentRss/50702.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iamtin/services/trackbacks/50702.html</trackback:ping><description><![CDATA[
		<p>无奈，寻找好的解决方法，把我现在擦屁股的现场记录下来。<br />我用GenericHibernateDAO，慢慢积累下来的，有这几个DetachedCriteria的方法：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> List findByDetachedCriteriaByPage(<br />        </span>
				<span style="COLOR: #0000ff">final</span>
				<span style="COLOR: #000000"> DetachedCriteria detachedCriteria, </span>
				<span style="COLOR: #0000ff">final</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> pagesize,<br />        </span>
				<span style="COLOR: #0000ff">final</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> pageno) {<br />        </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> getHibernateTemplate()<br />                   .findByCriteria(detachedCriteria, pagesize </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> pageno, pagesize);<br />    }<br /><br /></span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> getCountByDetachedCriteria(<br />        </span>
				<span style="COLOR: #0000ff">final</span>
				<span style="COLOR: #000000"> DetachedCriteria detachedCriteria) {<br />        Integer count </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> (Integer) getHibernateTemplate().execute(</span>
				<span style="COLOR: #0000ff">new</span>
				<span style="COLOR: #000000"> HibernateCallback() {<br />                    </span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000"> Object doInHibernate(Session session)<br />                        </span>
				<span style="COLOR: #0000ff">throws</span>
				<span style="COLOR: #000000"> HibernateException {<br />                        Criteria criteria </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> detachedCriteria.getExecutableCriteria(session);<br /><br />                        </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> criteria.setProjection(Projections.rowCount())<br />                                       .uniqueResult();<br />                    }<br />                }, </span>
				<span style="COLOR: #0000ff">true</span>
				<span style="COLOR: #000000">);<br /><br />        detachedCriteria.setProjection(</span>
				<span style="COLOR: #0000ff">null</span>
				<span style="COLOR: #000000">);<br /><br />        </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> count.intValue();<br />    }</span>
		</div>这是一对方法，经常一起用，一开始没有注意，后来发现有副作用。<br />生成一个DetachedCriteria，调用完getCountByDetachedCriteria以后再调用findByDetachedCriteriaByPage返回的结果居然是一个Integer……<br />原来getCountByDetachedCriteria方法里面对detachedCriteria.getExecutableCriteria(session)产生的criteria设定了Projection，这也影响到了DetachedCriteria本身，以后再用它作查询都回返回Projection的结果。<br />现在的解决方法是手动擦屁股，重新set Null。（我原先以为final关键字会保证detachedCriteria不被修改，后来发现只是引用不能修改，实例本身可以随便修改）请问大家，有什么更好的解决方案么，我决得复杂一点的话这个detachedCriteria如何能擦除回来？<br /><hr /><br />Reply from BJUG Groups by <strong><font color="#c88900">whimet：<br /></font></strong><font face="Courier New" size="2">这个问题在javaeye上已经讨论过：</font><a href="http://www.hibernate.org.cn/viewtopic.php?t=14657" target="_blank"><font face="Courier New" color="#551a8b" size="2">http://www.hibernate.org.cn/viewtopic.php?t=14657</font></a><font face="Courier New" size="2"><br />你这种情况还简单，若DetachedCriteria中包含排序设置就更不好办。 <br /></font><p>其实关键问题是DetachedCriteria.getExecutableCriteria返回的Criteria实例中已经包含了投影和排序信息，如果你­想先查总数， <br />就得先去掉这些信息；查完总数，再查实际数据时，又得加上这些信息。而Criteria可没提供对它改来改去的接口。 <br /></p><p>不过，仔细考察一下DetachedCriteria可以发现，它类似一种暂存了查询条件的值对象，通过与一个session对象结合生成 <br />一个“可执行的”Criteria，相当于先执行session.createCriteria，然后把自己保存的条件设置进去。 <br /></p><p>既然如此，我干脆自己提供一个类似的类，暂存查询条件，与session结合生成executableCriteria；但我先提供给用户一个只包含 <br />查询条件的Criteria实例，让用户先拿着它去查总数；然后再提供加入投影和排序信息的方法，让用户拿着它去查数据，不就解决问题了。 <br /></p><p>-------------- 示例代码： <br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">MyDetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <img src="http://www.blogjava.net/images/dot.gif" /> <br />Criteria c </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria( session );       </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">这里的c只包含查询条件，不包括投影和排序 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">c.setProjection( Projections.rowCount() ); <br />Integer total </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (Integer) c.uniqueResult();             </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">得到总数 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">dc.fillProjectionSetting( c );          </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把dc中保存的投影信息设置进去 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">dc.fillOrdersSetting( c );          </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把dc中保存的排序信息设置进去 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">List data </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> c.list();                           </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">取回数据 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br /><br /></span><span style="COLOR: #000000">--------------</span><span style="COLOR: #000000"> MyDetachedCriteria的代码： <br /></span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br /> * 单独的值对象，用于暂存与Criteria相关的查询条件，并可与Session结合生成一个可执行的Criteria&lt;br&gt; <br /> * &lt;br&gt; <br /> * 该类继承自DetachedCriteria只是为了保持接口兼容性，其实与DetachedCriteria没关系 &lt;br&gt; <br /> * （之所以叫“Detached”，是指与Session脱离） <br /> </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> MyDetachedCriteria </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> DetachedCriteria { <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Class entityClass; <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> ArrayList criterions </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ArrayList(); <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> ArrayList orders </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ArrayList(); <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Projection projection; <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> entityClass <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> MyDetachedCriteria( Class entityClass ) { <br />                </span><span style="COLOR: #0000ff">super</span><span style="COLOR: #000000">( entityClass.getName() ); <br />                </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.entityClass </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> entityClass; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#add(org.hibernate.criterion.Criter­ion) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> DetachedCriteria add( Criterion criterion ) { <br />                criterions.add( criterion ); <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#addOrder(org.hibernate.criterion.O­rder) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> DetachedCriteria addOrder( Order order ) { <br />                orders.add( order ); <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#setProjection(org.hibernate.criter­ion.Projection) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> DetachedCriteria setProjection( Projection projection ) { <br />                </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.projection </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> projection; <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> --------------------------------------------------------------------------- </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * 根据Session实例创建一个Criteria实例，并填充入此对象自身保存的条件后返回&lt;br&gt; <br />         * 注意：返回的Criteria实例不含排序和投影信息，用户需要自己调用fillOrdersSetting、 <br />         * fillProjectionSetting填充入排序和投影信息 <br />         * <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#getExecutableCriteria(org.hibernat­e.Session) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Criteria getExecutableCriteria( Session session ) { <br />                Criteria result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> session.createCriteria( entityClass ); <br /><br /><br />                </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> ( Iterator i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> criterions.iterator(); i.hasNext(); ) { <br />                        Criterion criterion </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ( Criterion ) i.next(); <br />                        result.add( criterion ); <br />                } <br /><br /><br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> result; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * 填充入排序信息设置 <br />         * <br />         * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> criteria <br />         * </span><span style="COLOR: #808080">@return</span><span style="COLOR: #008000"> <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Criteria fillOrdersSetting( Criteria criteria ) { <br />                </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> ( Iterator i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> orders.iterator(); i.hasNext(); ) { <br />                        Order order </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ( Order ) i.next(); <br />                        criteria.addOrder( order ); <br />                } <br /><br /><br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> criteria; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * 填充入投影信息设置 <br />         * <br />         * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> criteria <br />         * </span><span style="COLOR: #808080">@return</span><span style="COLOR: #008000"> <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Criteria fillProjectionSetting( Criteria criteria ) { <br />                criteria.setProjection( projection ); <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> criteria; <br />        } <br /><br /><br /><br />} <br /></span></div><hr /><p><br />Update 2006-6-6 20:52：<br />恩，谢谢诸位。想了想还是DetachedCriteria设计的目的和我想要的不一样。DetachedCriteria目前只是为了脱离session就可以构造，而并不是为了反复使用。<br />因为：1、它里面只包装了一个CriteriaImpl，所以实际上两者生命周期比较一致。而且每次getExecutableCriteria都直接返回这个CriteriaImpl，而不是重新创建，这就造成了容易被意外修改。 2、它没有提供与add对应的remove方法，这就造成它只能累积而不能擦拭（对于Order），用反射就太脏了。<br />whimet写的这个MyDetachedCriteria倒是可以解决问题，更符合我们想要复用DetachedCriteria的需求，不过我觉得调用起来接口上不太统一。Order和Projection一般不用复用，我想就可以不用实现DetachedCriteria接口，干脆修改GenericDAO的方法好了，写个接受List&lt;Criteria&gt;或者Criteria...的方法对应就可以了。反正觉得DetachedCriteria目前的实现是不如意，hack它吧……我就想提供remove这些Order和Projection的方法。<br />这里用反射解决了他遇到的Order的问题，大家可以参考，看来DetachedCriteria目前实现的还不够令人满意：<br /><a class="singleposttitle" id="viewpost1_TitleUrl" href="/rory/archive/2006/05/29/48850.html">关于Hibernate的DetachedCriteria查询的addOrder问题的解决办法</a></p><img src ="http://www.blogjava.net/iamtin/aggbug/50702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iamtin/" target="_blank">Tin</a> 2006-06-06 11:28 <a href="http://www.blogjava.net/iamtin/archive/2006/06/06/50702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>060523-JDO2和EJB3 JPA见闻</title><link>http://www.blogjava.net/iamtin/archive/2006/05/24/47759.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Wed, 24 May 2006 01:54:00 GMT</pubDate><guid>http://www.blogjava.net/iamtin/archive/2006/05/24/47759.html</guid><wfw:comment>http://www.blogjava.net/iamtin/comments/47759.html</wfw:comment><comments>http://www.blogjava.net/iamtin/archive/2006/05/24/47759.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iamtin/comments/commentRss/47759.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iamtin/services/trackbacks/47759.html</trackback:ping><description><![CDATA[
		<p>原来还有个JDO 2.0实现叫做JPOX。而且发现JDO 2.0的接口等定义是由Apache发布的，它是有Sun捐献的。<br />JPOX是2003年3月才开始开发的，目前实现支持JDO 1.0和JDO 2.0（JSR-243）规范。<br />JPOX号称支持JDOQL和SQL，而且以后也要实现EJB3持久化规范中的JPA（Java Persistence API）。<br />看来BEA有了Kodo，JBoss有了Hibernate，Oracle和Sun有了融合了TopLink的Glassfish中的EJB3持久化容器后，应该还有其它的厂商可以提供这样的东西出来。而且似乎JDO 2.0变成真正透明持久化后，从JDO商业实现转而支持JPA不会很难。本源上说JPA本来就是JDO 2.0风格被Gavin King的Hivernate搅合后出来的规范。<br />然后发现国内红工厂的Liberator EJB3也是一个JPA和JDO2兼容的EJB3容器，看来EJB3持久化引擎的实现还是不少的。<br />看了一篇介绍EJB3 API的讲座，是TSS和BeJUG提供的：<br /><a href="http://media.techtarget.com/tss/BeJUG/EJB3/index.html">http://media.techtarget.com/tss/BeJUG/EJB3/index.html</a><br />感觉很不错，现在听英文的PPT也比较流畅了。感想就是和Hibernate非常接近，其中EntityManager的概念和session非常相似。annotation的使用是代码级元数据的最佳实践。而且发现EJB3吸收了RoR中ActiveRecord的CoC（惯例代替配置）的理念，大部分的影射参数都有默认配置，而且可以通过annotation灵活的覆盖。所以说，认真学习Hibernate是有用的，Shift to EJB3 Persistence的时候就会比较容易。后面看到persistence.xml是为了在容器外使用EntityManager设计的，对于支持EJB3 Persistence的Java EE容器完全可以直接用EJB3 Persistence模型+元数据编程而不用额外的配置，这的确是非常方便的，提供了透明的持久化模型。而persistence.xml则保证J2SE下面也可以使用代码管理的EntityManager，带来可测试和可脱离Java EE Server的编程模型，更方便且可插拔。<br /></p>
<img src ="http://www.blogjava.net/iamtin/aggbug/47759.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iamtin/" target="_blank">Tin</a> 2006-05-24 09:54 <a href="http://www.blogjava.net/iamtin/archive/2006/05/24/47759.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate中获取关联属性为null的方式</title><link>http://www.blogjava.net/iamtin/archive/2006/05/11/45643.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Thu, 11 May 2006 05:09:00 GMT</pubDate><guid>http://www.blogjava.net/iamtin/archive/2006/05/11/45643.html</guid><wfw:comment>http://www.blogjava.net/iamtin/comments/45643.html</wfw:comment><comments>http://www.blogjava.net/iamtin/archive/2006/05/11/45643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iamtin/comments/commentRss/45643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iamtin/services/trackbacks/45643.html</trackback:ping><description><![CDATA[在Hibernate中获取有关联关系的pojo。我是指例如一个User（用户）拥有一个many-to-one的属性Unit（单位），但是有时有些用户的Unit属性为空，如果按单位查询用户的时候那些单位为null的用户就会被遗漏，如何调取呢？这本来是很简单的，但是我想当然的使用了Restriction.eq，但是不行，后来看了手册才发现应该使用Restrictions.isNul。下面是Test代码...<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_1_144_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1_144_Open_Text.style.display='none'; Codehighlighter1_1_144_Closed_Image.style.display='inline'; Codehighlighter1_1_144_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1_144_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1_144_Closed_Text.style.display='none'; Codehighlighter1_1_144_Open_Image.style.display='inline'; Codehighlighter1_1_144_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">    </span><span id="Codehighlighter1_1_144_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_1_144_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 为了获取一个unit为null的用户，如果传入一个null作为Uint实例则返回的结果总是0<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 因为执行的SQL为：(select * ) from USER_INF this_ where this_.UNIT_ID=''<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 这不是我们所期望的结果<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    @Test<br /><img id="Codehighlighter1_221_494_Open_Image" onclick="this.style.display='none'; Codehighlighter1_221_494_Open_Text.style.display='none'; Codehighlighter1_221_494_Closed_Image.style.display='inline'; Codehighlighter1_221_494_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_221_494_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_221_494_Closed_Text.style.display='none'; Codehighlighter1_221_494_Open_Image.style.display='inline'; Codehighlighter1_221_494_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> getUsersWhosUnitIsNullByRestrictionsEqNullUnit() </span><span id="Codehighlighter1_221_494_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_221_494_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        DetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> DetachedCriteria.forClass(User.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        dc.add(Restrictions.eq(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">unit</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        Criteria cri </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria(session);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getUsersWhosUnitIsNullByRestrictionsEqNullUnit():</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> cri.list().size());<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    <br /><img id="Codehighlighter1_505_647_Open_Image" onclick="this.style.display='none'; Codehighlighter1_505_647_Open_Text.style.display='none'; Codehighlighter1_505_647_Closed_Image.style.display='inline'; Codehighlighter1_505_647_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_505_647_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_505_647_Closed_Text.style.display='none'; Codehighlighter1_505_647_Open_Image.style.display='inline'; Codehighlighter1_505_647_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span id="Codehighlighter1_505_647_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_505_647_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 为了获取一个unit为null的用户，如果传入一个id为null的Unit实例则会报错，无法翻译为SQL<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 错误类型为：org.hibernate.TransientObjectException<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 这也不是我们所期望的结果<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    @Ignore<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    @Test(expected</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">TransientObjectException.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">)<br /><img id="Codehighlighter1_779_1087_Open_Image" onclick="this.style.display='none'; Codehighlighter1_779_1087_Open_Text.style.display='none'; Codehighlighter1_779_1087_Closed_Image.style.display='inline'; Codehighlighter1_779_1087_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_779_1087_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_779_1087_Closed_Text.style.display='none'; Codehighlighter1_779_1087_Open_Image.style.display='inline'; Codehighlighter1_779_1087_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> getUsersWhosUnitIsNullByRestrictionsEqUnitNullId() </span><span id="Codehighlighter1_779_1087_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_779_1087_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        Unit unit </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Unit();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(unit.getId());<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        DetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> DetachedCriteria.forClass(User.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        dc.add(Restrictions.eq(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">unit</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, unit));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        Criteria cri </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria(session);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getUsersWhosUnitIsNull():</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> cri.list().size());<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_1094_1257_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1094_1257_Open_Text.style.display='none'; Codehighlighter1_1094_1257_Closed_Image.style.display='inline'; Codehighlighter1_1094_1257_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1094_1257_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1094_1257_Closed_Text.style.display='none'; Codehighlighter1_1094_1257_Open_Image.style.display='inline'; Codehighlighter1_1094_1257_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span id="Codehighlighter1_1094_1257_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_1094_1257_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 为了获取一个unit为null的用户正确的方法应该是使用Restrictions.isNull方法<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 因为执行的SQL为：(select * ) from USER_INF this_ where this_.UNIT_ID is null<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />     * 这才是我们所希望的结果<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    @Test<br /><img id="Codehighlighter1_1330_1597_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1330_1597_Open_Text.style.display='none'; Codehighlighter1_1330_1597_Closed_Image.style.display='inline'; Codehighlighter1_1330_1597_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1330_1597_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1330_1597_Closed_Text.style.display='none'; Codehighlighter1_1330_1597_Open_Image.style.display='inline'; Codehighlighter1_1330_1597_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> getUsersWhosUnitIsNullByRestrictionsIsNull() </span><span id="Codehighlighter1_1330_1597_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_1330_1597_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        DetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> DetachedCriteria.forClass(User.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        dc.add(Restrictions.isNull(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">unit</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">));<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        Criteria cri </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria(session);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getUsersWhosUnitIsNullByRestrictionsIsNull():</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> cri.list().size());<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span></div><img src ="http://www.blogjava.net/iamtin/aggbug/45643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iamtin/" target="_blank">Tin</a> 2006-05-11 13:09 <a href="http://www.blogjava.net/iamtin/archive/2006/05/11/45643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>翻译的Hibernate的Session的javadoc</title><link>http://www.blogjava.net/iamtin/archive/2006/03/06/33910.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Mon, 06 Mar 2006 12:09:00 GMT</pubDate><guid>http://www.blogjava.net/iamtin/archive/2006/03/06/33910.html</guid><wfw:comment>http://www.blogjava.net/iamtin/comments/33910.html</wfw:comment><comments>http://www.blogjava.net/iamtin/archive/2006/03/06/33910.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/iamtin/comments/commentRss/33910.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iamtin/services/trackbacks/33910.html</trackback:ping><description><![CDATA[Hibernate的透明持久化用起来非常舒服，有时甚至忘记了数据库的存在。我身边的朋友经常会分不清save、saveOrUpdate、update的区别，lock、merge、replicate、refresh、evict甚至不知道是干什么用的。而且关于实体对象的生命周期也有很多概念不清，分不清transient、persistent、detached的区别，只是知道PO、VO这样的通俗叫法。其实这些概念都很简单，Hibernate的javadoc写的都很清楚，只需看看就能明白。所以我花了些时间将Hibernate 3.1.2中session的javadoc部分翻译了一下，旨在让那些因为Hibernate的“透明”而忘记了它基本概念的人们停下来再看看这些概念<img height="19" src="http://www.blogjava.net/Emoticons/74_74.gif" width="19" border="0" /><br /><br /><hr /><!-- ======== START OF CLASS DATA ======== --><h2><font size="-1">org.hibernate</font><br />Interface Session</h2><dl><dt><b>All Superinterfaces:</b></dt><dd><a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a></dd></dl><dl><dt><b>All Known Subinterfaces:</b></dt><dd><a title="interface in org.hibernate.event" href="/org/hibernate/event/EventSource.html">EventSource</a>, <a title="interface in org.hibernate.classic" href="/org/hibernate/classic/Session.html">Session</a></dd></dl><dl><dt><b>All Known Implementing Classes:</b></dt><dd><a title="class in org.hibernate.impl" href="/org/hibernate/impl/SessionImpl.html">SessionImpl</a></dd></dl><hr /><dl><dt>public interface <b>Session</b></dt><dt>extends <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a></dt></dl><p>Java应用程序与Hibernate之间的主要运行时接口。它是抽象了持久化服务概念的核心抽象API类。<br /><br /><tt>Session</tt>的生命周期绑定在一个物理的事务（tansaction）上面。（长的事务可能跨越多个数据库事物。）<br /><br /><tt>Session</tt>的主要功能是提供对映射的实体类实例的创建，读取和删除操作。实例可能以下面三种状态存在：<br /><br /><i>自由状态（transient）:</i> 不曾进行持久化，未与任何<tt>Session</tt>相关联<br /><i>持久化状态（persistent）:</i> 仅与一个<tt>Session</tt>相关联<br /><i>游离状态（detached）:</i> 已经进行过持久化，但当前未与任何<tt>Session</tt>相关联<br /><br />游离状态的实例可以通过调用<tt>save()</tt>、<tt>persist()</tt>或者<tt>saveOrUpdate()</tt>方法进行持久化。持久化实例可以通过调用<tt> delete()</tt>变成游离状态。通过<tt>get()</tt>或<tt>load()</tt>方法得到的实例都是持久化状态的。游离状态的实例可以通过调用 <tt>update()</tt>、0<tt>saveOrUpdate()</tt>、<tt>lock()</tt>或者<tt>replicate()</tt>进行持久化。游离或者自由状态下的实例可以通过调用<tt>merge()</tt>方法成为一个新的持久化实例。<br /><br /><tt>save()</tt>和<tt>persist()</tt>将会引发SQL的<tt>INSERT</tt>，<tt>delete()</tt>会引发SQL<tt>DELETE</tt>，而<tt>update()</tt>或<tt>merge()</tt>会引发SQL<tt>UPDATE</tt>。对<i>持久化（persistent）</i>实例的修改在刷新提交的时候会被检测到，它也会引起SQL<tt>UPDATE</tt>。<tt>saveOrUpdate()</tt>或者<tt>replicate()</tt>会引发SQL<tt>INSERT</tt>或者<tt>UPDATE</tt>。<br /><br />其具体实现并不一定是线程安全的。每个线程/事务应该从一个<tt>SessionFactory</tt>获取自己的session实例。<br /><br />如果其持久化对象类是可序列化的，则<tt>Session</tt>实例也是可序列化的。<br /><br />一个典型的事务应该使用下面的形式： </p><pre> Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     ...
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }
 </pre><br />如果<tt>Session</tt>抛出了异常, 事务必须回滚而session会被废弃。在异常发生后<tt>Session</tt>的内部状态可能会与数据库失去同步。 
<p></p><p></p><dl><dt><b>Author:</b></dt><dd>Gavin King 
</dd><dt><b>See Also:</b></dt><dd><a title="interface in org.hibernate" href="/org/hibernate/SessionFactory.html"><code>SessionFactory</code></a></dd></dl><hr /><p><!-- ======== NESTED CLASS SUMMARY ======== --><!-- =========== FIELD SUMMARY =========== --><!-- ======== CONSTRUCTOR SUMMARY ======== --><!-- ========== METHOD SUMMARY =========== --><a name="method_summary"><!-- --></a></p><table cellspacing="0" cellpadding="3" width="100%" summary="" border="1"><tbody><tr class="TableHeadingColor" bgcolor="#ccccff"><td colspan="2"><font size="+2"><b>Method Summary</b></font></td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Transaction.html">Transaction</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#beginTransaction()">beginTransaction</a></b>()</code><br />          开始一个工作单元并且返回相关联的<tt>事务（Transaction）</tt>对象。 </td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#cancelQuery()">cancelQuery</a></b>()</code><br />          终止执行当前查询。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#clear()">clear</a></b>()</code><br />          完整的清除这个session。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.sql" href="http://java.sun.com/j2se/1.3/docs/api/java/sql/Connection.html">Connection</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#close()">close</a></b>()</code><br />          停止这个<tt>Session</tt>，通过中断JDBC连接并且清空（cleaning up）它。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.sql" href="http://java.sun.com/j2se/1.3/docs/api/java/sql/Connection.html">Connection</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#connection()">connection</a></b>()</code><br />          获取这个Session的JDBC连接。<br /><br />如果这个session使用了积极的collection释放策略（如CMT-容器控制事务的环境下），关闭这个调用的连接的职责应该由当前应用程序负责。 </td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> boolean</code></font></td><td><code><b><a href="/org/hibernate/Session.html#contains(java.lang.Object)">contains</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          检查这个对象实例是否与当前的<tt>Session</tt>关联（即是否为Persistent状态）。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Criteria.html">Criteria</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#createCriteria(java.lang.Class)">createCriteria</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html">Class</a> persistentClass)</code><br />          为给定的实体类或它的超类创建一个新的<tt>Criteria</tt>实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Criteria.html">Criteria</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#createCriteria(java.lang.Class, java.lang.String)">createCriteria</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html">Class</a> persistentClass, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> alias)</code><br />          根据给定的实体类或者它的超类创建一个新的<tt>Criteria</tt>实例，并赋予它（实体类）一个别名。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Criteria.html">Criteria</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#createCriteria(java.lang.String)">createCriteria</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName)</code><br />          根据给定的实体的名称（name），创建一个新的<tt>Criteria</tt>实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Criteria.html">Criteria</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#createCriteria(java.lang.String, java.lang.String)">createCriteria</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> alias)</code><br />          根据给定的实体的名称（name），创建一个新的<tt>Criteria</tt>实例，并赋予它（实体类）一个别名</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Query.html">Query</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#createFilter(java.lang.Object, java.lang.String)">createFilter</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> collection, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> queryString)</code><br />          根据给定的collection和过滤字符串（查询条件）创建一个新的<tt>Query</tt>实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Query.html">Query</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#createQuery(java.lang.String)">createQuery</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> queryString)</code><br />          根据给定的HQL查询条件创建一个新的<tt>Query</tt>实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/SQLQuery.html">SQLQuery</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#createSQLQuery(java.lang.String)">createSQLQuery</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> queryString)</code><br />          根据给定的SQL查询条件创建一个新的<tt>SQLQuery</tt>实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#delete(java.lang.Object)">delete</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          从数据库中移除持久化（persistent）对象的实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#delete(java.lang.String, java.lang.Object)">delete</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          从数据库中移除持久化（persistent）对象的实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#disableFilter(java.lang.String)">disableFilter</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> filterName)</code><br />          禁用当前session的名称过滤器。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.sql" href="http://java.sun.com/j2se/1.3/docs/api/java/sql/Connection.html">Connection</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#disconnect()">disconnect</a></b>()</code><br />          断开<tt>Session</tt>与当前的JDBC连接。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Filter.html">Filter</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#enableFilter(java.lang.String)">enableFilter</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> filterName)</code><br />          打开当前session的名称过滤器。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#evict(java.lang.Object)">evict</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          将当前对象实例从session缓存中清除。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#flush()">flush</a></b>()</code><br />          强制提交刷新（flush）<tt>Session</tt>。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#get(java.lang.Class, java.io.Serializable)">get</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html">Class</a> clazz, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id)</code><br />          根据给定标识和实体类返回持久化对象的实例，如果没有符合条件的持久化对象实例则返回null。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#get(java.lang.Class, java.io.Serializable, org.hibernate.LockMode)">get</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html">Class</a> clazz, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id, <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a> lockMode)</code><br />          根据给定标识和实体类返回持久化对象的实例，如果没有符合条件的持久化对象实例则返回null。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#get(java.lang.String, java.io.Serializable)">get</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id)</code><br />          返回与给定的实体命名和标识匹配的持久化实例，如果没有对应的持久化实例则返回null。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#get(java.lang.String, java.io.Serializable, org.hibernate.LockMode)">get</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id, <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a> lockMode)</code><br />          返回与给定的实体类和标识所匹配的持久化实例，如果没有对应的持久化实例则返回null。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class in org.hibernate" href="/org/hibernate/CacheMode.html">CacheMode</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getCacheMode()">getCacheMode</a></b>()</code><br />          得到当前的缓存模式。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getCurrentLockMode(java.lang.Object)">getCurrentLockMode</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          检测给定对象当前的锁定级别。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Filter.html">Filter</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getEnabledFilter(java.lang.String)">getEnabledFilter</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> filterName)</code><br />          根据名称获取一个当前允许的过滤器（filter）。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class in org.hibernate" href="/org/hibernate/EntityMode.html">EntityMode</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getEntityMode()">getEntityMode</a></b>()</code><br />          获取这个session有效的实体模式。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getEntityName(java.lang.Object)">getEntityName</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          返回一个持久化对象的实体名称。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class in org.hibernate" href="/org/hibernate/FlushMode.html">FlushMode</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getFlushMode()">getFlushMode</a></b>()</code><br />          获得当前的刷新提交（flush）模式。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getIdentifier(java.lang.Object)">getIdentifier</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          获取给定的实体对象实例在<tt>Session</tt>的缓存中的标识，如果该实例是自由状态（Transient）的或者与其它<tt>Session</tt>关联则抛出一个异常。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Query.html">Query</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getNamedQuery(java.lang.String)">getNamedQuery</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> queryName)</code><br />          从映射文件中根据给定的查询的名称字符串获取一个<tt>Query（查询）</tt>实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Session.html">Session</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getSession(org.hibernate.EntityMode)">getSession</a></b>(<a title="class in org.hibernate" href="/org/hibernate/EntityMode.html">EntityMode</a> entityMode)</code><br />          根据给定的实体模式（Entity Mode）开始一个新的有效的Session。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/SessionFactory.html">SessionFactory</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getSessionFactory()">getSessionFactory</a></b>()</code><br />          获取创建这个session的<tt>SessionFactory</tt>实例。 </td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate.stat" href="/org/hibernate/stat/SessionStatistics.html">SessionStatistics</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getStatistics()">getStatistics</a></b>()</code><br />          获取这个session的统计信息。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="interface in org.hibernate" href="/org/hibernate/Transaction.html">Transaction</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#getTransaction()">getTransaction</a></b>()</code><br />          获取与这个session关联的<tt>Transaction（事务）</tt>实例。 instance associated with this session.</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> boolean</code></font></td><td><code><b><a href="/org/hibernate/Session.html#isConnected()">isConnected</a></b>()</code><br />          检查当前<tt>Session</tt>是否处于连接状态。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> boolean</code></font></td><td><code><b><a href="/org/hibernate/Session.html#isDirty()">isDirty</a></b>()</code><br />          当前<tt>Session</tt>是否包含需要与数据库同步的（数据状态）变化 ？如果我们刷新提交（flush）这个session是否会有SQL执行？</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> boolean</code></font></td><td><code><b><a href="/org/hibernate/Session.html#isOpen()">isOpen</a></b>()</code><br />          检查当前<tt>Session</tt>是否仍然打开。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#load(java.lang.Class, java.io.Serializable)">load</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html">Class</a> theClass, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id)</code><br />          在符合条件的实例存在的情况下，根据给定的实体类和标识返回持久化状态的实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#load(java.lang.Class, java.io.Serializable, org.hibernate.LockMode)">load</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html">Class</a> theClass, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id, <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a> lockMode)</code><br />          在符合条件的实例存在的情况下，根据给定的实体类、标识及指定的锁定等级返回持久化状态的实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#load(java.lang.Object, java.io.Serializable)">load</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id)</code><br />          将与给定的标示对应的持久化状态（值）复制到给定的自由状态（trasient）实例上。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#load(java.lang.String, java.io.Serializable)">load</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id)</code><br />          在符合条件的实例存在的情况下，根据给定的实体类和标识返回持久化状态的实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#load(java.lang.String, java.io.Serializable, org.hibernate.LockMode)">load</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a> id, <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a> lockMode)</code><br />          在符合条件的实例存在的情况下，根据给定的实体类、标识及指定的锁定等级返回持久化状态的实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#lock(java.lang.Object, org.hibernate.LockMode)">lock</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object, <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a> lockMode)</code><br />          从给定的对象上获取指定的锁定级别。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#lock(java.lang.String, java.lang.Object, org.hibernate.LockMode)">lock</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object, <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a> lockMode)</code><br />          从给定的对象上获取指定的锁定级别。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#merge(java.lang.Object)">merge</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          将给定的对象的状态复制到具有相同标识的持久化对象上。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#merge(java.lang.String, java.lang.Object)">merge</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          将给定的对象的状态复制到具有相同标识的持久化对象上。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#persist(java.lang.Object)">persist</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          将一个自由状态（transient）的实例持久化。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#persist(java.lang.String, java.lang.Object)">persist</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          将一个自由状态（transient）的实例持久化。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#reconnect()">reconnect</a></b>()</code><br />          <b>不推荐的。</b> <i>手工的重新连接只应用于应用程序提供连接的情况，在这种情况下或许应该使用<a href="/org/hibernate/Session.html#reconnect(java.sql.Connection)"><code>reconnect(java.sql.Connection)</code></a>。</i></td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#reconnect(java.sql.Connection)">reconnect</a></b>(<a title="class or interface in java.sql" href="http://java.sun.com/j2se/1.3/docs/api/java/sql/Connection.html">Connection</a> connection)</code><br />          重新连接到给定的JDBC连接。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#refresh(java.lang.Object)">refresh</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          从数据库中重新读取给定实例的状态。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#refresh(java.lang.Object, org.hibernate.LockMode)">refresh</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object, <a title="class in org.hibernate" href="/org/hibernate/LockMode.html">LockMode</a> lockMode)</code><br />          根据指定的<tt>锁定模式（LockMode）</tt>，从数据库中重新读取给定实例的状态。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#replicate(java.lang.Object, org.hibernate.ReplicationMode)">replicate</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object, <a title="class in org.hibernate" href="/org/hibernate/ReplicationMode.html">ReplicationMode</a> replicationMode)</code><br />          使用当前的标识值持久化给定的游离状态（Transient）的实体。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#replicate(java.lang.String, java.lang.Object, org.hibernate.ReplicationMode)">replicate</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object, <a title="class in org.hibernate" href="/org/hibernate/ReplicationMode.html">ReplicationMode</a> replicationMode)</code><br />          使用当前的标识值持久化给定的游离状态（Transient）的实体。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#save(java.lang.Object)">save</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          首先为给定的自由状态（Transient）的对象（根据配置）生成一个标识并赋值，然后将其持久化。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> <a title="class or interface in java.io" href="http://java.sun.com/j2se/1.3/docs/api/java/io/Serializable.html">Serializable</a></code></font></td><td><code><b><a href="/org/hibernate/Session.html#save(java.lang.String, java.lang.Object)">save</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          首先为给定的自由状态（Transient）的对象（根据配置）生成一个标识并赋值，然后将其持久化。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#saveOrUpdate(java.lang.Object)">saveOrUpdate</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          根据给定的实例的标识属性的值（注：可以指定unsaved-value。一般默认null。）来决定执行 <tt>save()</tt> 或<tt>update()</tt>操作。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#saveOrUpdate(java.lang.String, java.lang.Object)">saveOrUpdate</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          根据给定的实例的标识属性的值（注：可以指定unsaved-value。一般默认null。）来决定执行 <tt>save()</tt> 或<tt>update()</tt>操作。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#setCacheMode(org.hibernate.CacheMode)">setCacheMode</a></b>(<a title="class in org.hibernate" href="/org/hibernate/CacheMode.html">CacheMode</a> cacheMode)</code><br />          设置刷新提交模式。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#setFlushMode(org.hibernate.FlushMode)">setFlushMode</a></b>(<a title="class in org.hibernate" href="/org/hibernate/FlushMode.html">FlushMode</a> flushMode)</code><br />          设置刷新提交模式。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#setReadOnly(java.lang.Object, boolean)">setReadOnly</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> entity, boolean readOnly)</code><br />          将一个未经更改的持久化对象设置为只读模式，或者将一个只读对象标记为可以修改的模式。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#update(java.lang.Object)">update</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          根据给定的detached（游离状态）对象实例的标识更新对应的持久化实例。</td></tr><tr class="TableRowColor" bgcolor="white"><td valign="top" align="right" width="1%"><font size="-1"><code> void</code></font></td><td><code><b><a href="/org/hibernate/Session.html#update(java.lang.String, java.lang.Object)">update</a></b>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html">String</a> entityName, <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html">Object</a> object)</code><br />          根据给定的detached（游离状态）对象实例的标识更新对应的持久化实例。</td></tr></tbody></table>  
<p><!-- ============ FIELD DETAIL =========== --><!-- ========= CONSTRUCTOR DETAIL ======== --></p><img src ="http://www.blogjava.net/iamtin/aggbug/33910.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iamtin/" target="_blank">Tin</a> 2006-03-06 20:09 <a href="http://www.blogjava.net/iamtin/archive/2006/03/06/33910.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DomainModel中的hashCode和equals方法</title><link>http://www.blogjava.net/iamtin/archive/2006/02/15/30775.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Wed, 15 Feb 2006 03:34:00 GMT</pubDate><guid>http://www.blogjava.net/iamtin/archive/2006/02/15/30775.html</guid><wfw:comment>http://www.blogjava.net/iamtin/comments/30775.html</wfw:comment><comments>http://www.blogjava.net/iamtin/archive/2006/02/15/30775.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/iamtin/comments/commentRss/30775.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/iamtin/services/trackbacks/30775.html</trackback:ping><description><![CDATA[<P>hashCode:<BR>他是用来产生hash值的，用在Hashtable上，也包括HashMap等实现。<BR>hashCode的基本约定是：<BR>1、hashCode方法在同一个object上不管被调用了多少次，在同一次执行的Java程序中，hashCode方法必须返回一个持续相同的int。在object被修改时，不给equals方法提供信息。这个int值在同一个程序的两次不同执行过程中（同一程序执行两次），不需要保持恒定。<BR>2、如果两个object通过equals()方法判断相等，则调用它们的hashCode方法应该产生相同的结果。<BR>3、两个通过equals()方法判定不相等的object，调用它们的hashCOde方法并不是必须返回不同的结果。但是，成序言们应该意识到对于不相等的object产生不同的int结果有助于提升hashtables的效率。<BR>一般技术上，通过将object的内部地址转换为integer的方法来产生hashCode，但这不是必需的。</P>
<P>equals:<BR>就是判断是否相等的方法。<BR>基本约定如下：<BR>自反：就是x.equals(x)应该返回true<BR>对称：x.equals(y)返回true则y.equals(x)返回true<BR>传递：x.euqls(y)==true，y.equals(z)==true，那么x.equals(z)也必须返回true<BR>持续性：就是说如果x.equals(y)==true，不管它调用多少次都应该返回true<BR>非空引用：x.equals(null)应该返回false</P>
<P>准则原因这里：<BR><A href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode">http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode</A>()<BR><BR>在实际Domain中如何实现他们比较好呢？从eclipseWork中的模板生成如下：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG id=Codehighlighter1_34_365_Open_Image onclick="this.style.display='none'; Codehighlighter1_34_365_Open_Text.style.display='none'; Codehighlighter1_34_365_Closed_Image.style.display='inline'; Codehighlighter1_34_365_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_34_365_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_34_365_Closed_Text.style.display='none'; Codehighlighter1_34_365_Open_Image.style.display='inline'; Codehighlighter1_34_365_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">boolean</SPAN><SPAN style="COLOR: #000000">&nbsp;equals(Object&nbsp;rhs)&nbsp;</SPAN><SPAN id=Codehighlighter1_34_365_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_34_365_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_61_97_Open_Image onclick="this.style.display='none'; Codehighlighter1_61_97_Open_Text.style.display='none'; Codehighlighter1_61_97_Closed_Image.style.display='inline'; Codehighlighter1_61_97_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_61_97_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_61_97_Closed_Text.style.display='none'; Codehighlighter1_61_97_Open_Image.style.display='inline'; Codehighlighter1_61_97_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(rhs&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_61_97_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_61_97_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_136_172_Open_Image onclick="this.style.display='none'; Codehighlighter1_136_172_Open_Text.style.display='none'; Codehighlighter1_136_172_Closed_Image.style.display='inline'; Codehighlighter1_136_172_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_136_172_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_136_172_Closed_Text.style.display='none'; Codehighlighter1_136_172_Open_Image.style.display='inline'; Codehighlighter1_136_172_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(rhs&nbsp;</SPAN><SPAN style="COLOR: #0000ff">instanceof</SPAN><SPAN style="COLOR: #000000">&nbsp;Town))&nbsp;</SPAN><SPAN id=Codehighlighter1_136_172_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_136_172_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Town&nbsp;that&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Town)&nbsp;rhs;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_270_306_Open_Image onclick="this.style.display='none'; Codehighlighter1_270_306_Open_Text.style.display='none'; Codehighlighter1_270_306_Closed_Image.style.display='inline'; Codehighlighter1_270_306_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_270_306_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_270_306_Closed_Text.style.display='none'; Codehighlighter1_270_306_Open_Image.style.display='inline'; Codehighlighter1_270_306_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;((</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.getId()&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;(that.getId()&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN id=Codehighlighter1_270_306_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_270_306_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.getId().equals(that.getId()));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG id=Codehighlighter1_22_297_Open_Image onclick="this.style.display='none'; Codehighlighter1_22_297_Open_Text.style.display='none'; Codehighlighter1_22_297_Closed_Image.style.display='inline'; Codehighlighter1_22_297_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_22_297_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_22_297_Closed_Text.style.display='none'; Codehighlighter1_22_297_Open_Image.style.display='inline'; Codehighlighter1_22_297_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;hashCode()&nbsp;</SPAN><SPAN id=Codehighlighter1_22_297_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_22_297_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_57_259_Open_Image onclick="this.style.display='none'; Codehighlighter1_57_259_Open_Text.style.display='none'; Codehighlighter1_57_259_Closed_Image.style.display='inline'; Codehighlighter1_57_259_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_57_259_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_57_259_Closed_Text.style.display='none'; Codehighlighter1_57_259_Open_Image.style.display='inline'; Codehighlighter1_57_259_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.hashValue&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_57_259_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_57_259_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;result&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">17</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;idValue&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.getId()&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">?</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.getId().hashCode();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(result&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">37</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;idValue;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.hashValue&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;result;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.hashValue;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV><BR>下一步还要继续研究，上面的的方法很类似于“<SPAN style="COLOR: #999999">Java theory and practice: </SPAN>Hashing it out”<BR><A href="http://www-128.ibm.com/developerworks/java/library/j-jtp05273.html">http://www-128.ibm.com/developerworks/java/library/j-jtp05273.html</A><img src ="http://www.blogjava.net/iamtin/aggbug/30775.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/iamtin/" target="_blank">Tin</a> 2006-02-15 11:34 <a href="http://www.blogjava.net/iamtin/archive/2006/02/15/30775.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>