﻿<?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-VIRGIN FOREST OF JAVA-文章分类-Hibernate</title><link>http://www.blogjava.net/RR00/category/2561.html</link><description>不要埋头苦干，要学习，学习，再学习。。。。。
&lt;br&gt;
powered  by &lt;font color='orange'&gt;R.Zeus&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 22:35:02 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 22:35:02 GMT</pubDate><ttl>60</ttl><item><title>timestamp and date in hibernate</title><link>http://www.blogjava.net/RR00/articles/83984.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Tue, 28 Nov 2006 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/83984.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/83984.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/83984.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/83984.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/83984.html</trackback:ping><description><![CDATA[for timestamp and date in hibernate.hbm.xml,the compare method something different.<br /> * timestamp support the hh:mm:ss and date will ignore that or make missstake.see the <br /> * hibernate reference.<br />so save the same java.util.date,but different in the database.<img src ="http://www.blogjava.net/RR00/aggbug/83984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-11-28 10:32 <a href="http://www.blogjava.net/RR00/articles/83984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>simple Database Connection Pool in hibernate </title><link>http://www.blogjava.net/RR00/articles/79816.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 08 Nov 2006 04:23:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/79816.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/79816.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/79816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/79816.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/79816.html</trackback:ping><description><![CDATA[
		<table>
				<tbody>
						<tr bgcolor="#1bbacd">
								<td>
										<p> public void closeConnection(Connection conn) throws SQLException {</p>
										<p>  if ( log.isDebugEnabled() ) checkedOut--;</p>
										<p>
												<font color="#ee82ee">
														<font style="BACKGROUND-COLOR: #ffffff">
																<font color="#0000ff">//synchronized pool to avoid concurrence error.</font>  <br /></font>
												</font>synchronized (pool) {<br />   int currentSize = pool.size();<br />   if ( currentSize &lt; poolSize ) {<br />    if ( log.isTraceEnabled() ) log.trace("returning connection to pool, pool size: " + (currentSize + 1) );<br /><font style="BACKGROUND-COLOR: #ffffff" color="#0000ff"><br />//add to pool</font><font color="#ee82ee">  </font><br />    pool.add(conn);<br />    return;<br />   }<br />  }</p>
										<p>  log.debug("closing JDBC connection");</p>
										<p>  conn.close();</p>
										<p> }</p>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table>
				<tbody>
						<tr bgcolor="#1bbacd">
								<td>
										<p> public Connection getConnection() throws SQLException {</p>
										<p>  if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );</p>
										<p>
												<font style="BACKGROUND-COLOR: #ffffff" color="#0000ff">//synchronized pool to avoid concurrence error</font>
												<font color="#ee82ee">  </font> <br /> synchronized (pool) {<br />   if ( !pool.isEmpty() ) {<br /><br /><font color="#0000ff"><font style="BACKGROUND-COLOR: #ffffff">//if the pool is not empty,return connection from the pool</font>  <br /></font><br />    <br />    int last = pool.size() - 1;<br />    if ( log.isTraceEnabled() ) {<br />     log.trace("using pooled JDBC connection, pool size: " + last);<br />     checkedOut++;<br />    }<br />    Connection pooled = (Connection) pool.remove(last);<br />    if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );<br />    if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);<br />    return pooled;<br />   }<br />  }<br /></p>
										<p>  log.debug("opening new JDBC connection");<br /><font style="BACKGROUND-COLOR: #ffffff" color="#0000ff">//create new connection.<br /></font>  Connection conn = DriverManager.getConnection(url, connectionProps);<br />  if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );<br />  if ( conn.getAutoCommit()!=autocommit ) conn.setAutoCommit(autocommit);</p>
										<p>  if ( log.isDebugEnabled() ) {<br />   log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );<br />  }<br />  if ( log.isTraceEnabled() ) checkedOut++;</p>
										<p>  return conn;<br /> }</p>
								</td>
						</tr>
				</tbody>
		</table>
		<br />so you can see that when the connection will close,it actually not close and add to the pool if the pool size is not full.<br /><br />in other way , we can firstly create a number of connection in the pool and when the pool is used out then create new connection to the call.<br /><br />I will see the C3P0ConnectionProvider next.<br /><br />A connection provider that uses java.sql.DriverManager. This provider<br /> also implements a very <font color="#ff1493">rudimentary</font> connection pool.<br /><br />Note that you have to copy the required library into your classpath and use different connection pooling settings if you want to use a <font color="#ff1493">production-quality</font> third party JDBC pooling software. <br /><br /><br /><img src ="http://www.blogjava.net/RR00/aggbug/79816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-11-08 12:23 <a href="http://www.blogjava.net/RR00/articles/79816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate support PlaceHolder '${}'</title><link>http://www.blogjava.net/RR00/articles/79652.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Tue, 07 Nov 2006 09:25:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/79652.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/79652.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/79652.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/79652.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/79652.html</trackback:ping><description><![CDATA[PropertiesHelper.resolvePlaceHolders( copy );<br /><br /><table><tbody><tr><td bgcolor="#fdab9d"><span class="postbody" twffan="done">public static String resolvePlaceHolder(String property) {<br />  if ( property.indexOf( PLACEHOLDER_START ) &lt; 0 ) {<br />   return property;<br />  }<br />  StringBuffer buff = new StringBuffer();<br />  char[] chars = property.toCharArray();<br />  for ( int pos = 0; pos &lt; chars.length; pos++ ) {<br />   if ( chars[pos] == '$' ) {<br />    // peek ahead<br />    if ( chars[pos+1] == '{' ) {<br />     // we have a placeholder, spin forward till we find the end<br />     String systemPropertyName = "";<br />     int x = pos + 2;<br />     for (  ; x &lt; chars.length &amp;&amp; chars[x] != '}'; x++ ) {<br />      systemPropertyName += chars[x];<br />      // if we reach the end of the string w/o finding the<br />      // matching end, that is an exception<br />      if ( x == chars.length - 1 ) {<br />       throw new IllegalArgumentException( "unmatched placeholder start [" + property + "]" );<br />      }<br />     }<br />     String systemProperty = extractFromSystem( systemPropertyName );<br />     buff.append( systemProperty == null ? "" : systemProperty );<br />     pos = x + 1;<br />     // make sure spinning forward did not put us past the end of the buffer...<br />     if ( pos &gt;= chars.length ) {<br />      break;<br />     }<br />    }<br />   }<br />   buff.append( chars[pos] );<br />  }<br />  String rtn = buff.toString();<br />  return StringHelper.isEmpty( rtn ) ? null : rtn;</span></td></tr></tbody></table><br /><table><tbody><tr><td bgcolor="#fdab9d"><span class="postbody" twffan="done">extractFromSystem( systemPropertyName )<br /><br />private static String extractFromSystem(String systemPropertyName) {<br />  try {<br />   return System.getProperty( systemPropertyName );<br />  }<br />  catch( Throwable t ) {<br />   return null;<br />  }<br /> }<br /><br /></span></td></tr></tbody></table><br />this properties can use in <strong>hibernate.cfg.xml</strong><img src ="http://www.blogjava.net/RR00/aggbug/79652.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-11-07 17:25 <a href="http://www.blogjava.net/RR00/articles/79652.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>An JoinedIterator is an Iterator that wraps a number of Iterators.</title><link>http://www.blogjava.net/RR00/articles/79643.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Tue, 07 Nov 2006 09:00:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/79643.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/79643.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/79643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/79643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/79643.html</trackback:ping><description><![CDATA[An JoinedIterator is an Iterator that wraps a number of Iterators.<br /><br /> *This class makes multiple iterators look like one to the caller.<br /> * When any method from the Iterator interface is called, the JoinedIterator<br /> * will delegate to a single underlying Iterator. The JoinedIterator will<br /> * invoke the Iterators in sequence until all Iterators are exhausted.<img src ="http://www.blogjava.net/RR00/aggbug/79643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-11-07 17:00 <a href="http://www.blogjava.net/RR00/articles/79643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Performance: Hibernate startup time</title><link>http://www.blogjava.net/RR00/articles/78093.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 30 Oct 2006 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/78093.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/78093.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/78093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/78093.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/78093.html</trackback:ping><description><![CDATA[
		<p>From: <a href="http://www.hibernate.org/194.html">Performance: Hibernate startup time</a><br /><br />The following tips hints how to make Hibernate startup faster.</p>
		<a name="A2">
		</a>
		<h2>Only add the mapping files you need!</h2>
		<blockquote>
				<p>If you are running some few JUnit tests for a 400++ classes project you probably don't hit every class in those tests and thus do not need to add all those hbm.xml's to the Configuration. Go look at Hibernate's test suite on how you <strong>could</strong> let your TestCase decide what classes should be defined in the mapping.</p>
		</blockquote>
		<a name="A3">
		</a>
		<h2>Use serialized XML documents when configuring Configuration</h2>
		<blockquote>
				<p>When building the configuration 40-60% of the time is used by the XML parsers and Dom4j to read up the XML document. Significant performance increases can be done by serializing the Document object's to disc once, and afterwards just add them to the configuration by deserializing them first.</p>
				<p>In the current cvs we have an experimental Configuration.addCachableFile() method that can be used as inspiration for previous Hibernate versions.</p>
				<pre class="code">public Configuration addCachableFile(String xmlFile) throws MappingException {        
        try {
            File file = new File(xmlFile);
            File lazyfile = new File(xmlFile + ".bin");
            org.dom4j.Document doc = null; 
            List errors = new ArrayList();
            if(file.exists() &amp;&amp; lazyfile.exists() &amp;&amp; file.lastModified()&lt;lazyfile.lastModified()) {
                log.info("Mapping lazy file: " + lazyfile.getPath());
                ObjectInputStream oip = null;
                oip = new ObjectInputStream(new FileInputStream(lazyfile));
                doc = (org.dom4j.Document) oip.readObject();
                oip.close(); 
            } else {
                doc = xmlHelper.createSAXReader(xmlFile, errors, entityResolver).read( file );
                log.info("Writing lazy file to " + lazyfile);
                ObjectOutputStream oup = new ObjectOutputStream(new FileOutputStream(lazyfile));
                oup.writeObject(doc);
                oup.flush();
                oup.close();
            }
            
            if ( errors.size()!=0 ) throw new MappingException( "invalid mapping", (Throwable) errors.get(0) );
            add(doc);
            return this;
        }
        catch (Exception e) {
            log.error("Could not configure datastore from file: " + xmlFile, e);
            throw new MappingException(e);
        }
    }
</pre>
		</blockquote>
		<a name="A4">
		</a>
		<h2>Disable Hibernates usage of cglib reflection optimizer</h2>
		<blockquote>
				<p>Put the following line in hibernate.properties:</p>
				<pre class="code">hibernate.cglib.use_reflection_optimizer=false
</pre>
				<p>It will make Hibernate start faster since it does not try to build cglib-enhanced objects to access getter/setters.</p>
				<p>Note: It will have in impact on overall runtime performance since Hibernate will be forced to use standard JDK reflection for access. So it is most useful during development. (You will also get better error messages in some situations when the optimizer is disabled ;)</p>
		</blockquote>
		<!-- End Body -->
		<div twffan="done">
				<br />
				<table style="BACKGROUND: #a0a0a0; WIDTH: 100%" cellspacing="0" cellpadding="0" border="0">
						<tbody>
								<tr>
										<td width="100%"> </td>
										<td onmouseup="fireClickEventOnChild(this, 'A')" class="topNav2" onmouseover="mover(this, '#cccccc')" onmouseout="mout(this, '#a0a0a0')" valign="center">
												<a onfocus="if (this.blur) this.blur()" href="http://www.hibernate.org/194.html?comid=0&amp;cmd=newcom">
														<span class="topNav2Link" twffan="done">NEW COMMENT</span>
												</a>
										</td>
								</tr>
						</tbody>
				</table>
				<br />
				<table style="BACKGROUND: #cccccc" cellspacing="0" cellpadding="0" width="100%" border="0">
						<tbody>
								<tr>
										<td style="FLOAT: left; MARGIN-LEFT: 4px; WIDTH: 100%" nowrap="">
												<a href="http://www.hibernate.org/194.220.html">Serializing the Configuration object</a>
												<div twffan="done">
												</div>
										</td>
										<td class="label" style="WIDTH: 150px; COLOR: black" nowrap="">04 May 2004, 12:37 
<div twffan="done"></div></td>
										<td class="label" style="COLOR: black" nowrap="">luish 
<div twffan="done"></div></td>
								</tr>
								<tr>
										<td style="PADDING-RIGHT: 4px; PADDING-LEFT: 4px; BACKGROUND: #eeeeee; PADDING-BOTTOM: 4px; PADDING-TOP: 4px" colspan="3">
												<pre>Another approach would be to serialize the whole Configuration 
object. What do you think about this? I have submitted a patch to  
the Jira to make the Configuration Serializable (see bugs 492 and 
147).</pre>
										</td>
								</tr>
								<tr>
										<td bgcolor="#ffffff" colspan="3"> </td>
								</tr>
								<tr>
										<td style="FLOAT: left; MARGIN-LEFT: 4px; WIDTH: 100%" nowrap="">
												<a href="http://www.hibernate.org/194.275.html">addLazyFile() not there.</a>
												<div twffan="done">
												</div>
										</td>
										<td class="label" style="WIDTH: 150px; COLOR: black" nowrap="">06 Jul 2004, 11:50 
<div twffan="done"></div></td>
										<td class="label" style="COLOR: black" nowrap="">gstamp 
<div twffan="done"></div></td>
								</tr>
								<tr>
										<td style="PADDING-RIGHT: 4px; PADDING-LEFT: 4px; BACKGROUND: #eeeeee; PADDING-BOTTOM: 4px; PADDING-TOP: 4px" colspan="3">
												<pre>I can't fine addLazyFile() in CVS.  Is it still supposed to be there?</pre>
										</td>
								</tr>
								<tr>
										<td bgcolor="#ffffff" colspan="3"> </td>
								</tr>
								<tr>
										<td style="FLOAT: left; MARGIN-LEFT: 4px; WIDTH: 100%" nowrap="">
												<a href="http://www.hibernate.org/194.328.html">Hibernate3 feature</a>
												<div twffan="done">
												</div>
										</td>
										<td class="label" style="WIDTH: 150px; COLOR: black" nowrap="">31 Aug 2004, 11:13 
<div twffan="done"></div></td>
										<td class="label" style="COLOR: black" nowrap="">gavin 
<div twffan="done"></div></td>
								</tr>
								<tr>
										<td style="PADDING-RIGHT: 4px; PADDING-LEFT: 4px; BACKGROUND: #eeeeee; PADDING-BOTTOM: 4px; PADDING-TOP: 4px" colspan="3">
												<pre>Try the Hibernate3 module (or just the alpha release)</pre>
										</td>
								</tr>
								<tr>
										<td bgcolor="#ffffff" colspan="3"> </td>
								</tr>
								<tr>
										<td style="FLOAT: left; MARGIN-LEFT: 4px; WIDTH: 100%" nowrap="">
												<a href="http://www.hibernate.org/194.469.html">Information update?</a>
												<div twffan="done">
												</div>
										</td>
										<td class="label" style="WIDTH: 150px; COLOR: black" nowrap="">30 Mar 2005, 07:54 
<div twffan="done"></div></td>
										<td class="label" style="COLOR: black" nowrap="">gruberc 
<div twffan="done"></div></td>
								</tr>
								<tr>
										<td style="PADDING-RIGHT: 4px; PADDING-LEFT: 4px; BACKGROUND: #eeeeee; PADDING-BOTTOM: 4px; PADDING-TOP: 4px" colspan="3">
												<pre>The information on this page does not seem to be correct any
more. With Hibernate 3.0rc1, there is no Configuration.addLazyFile()
any more, but addCacheableFile(). How should it be used?</pre>
										</td>
								</tr>
								<tr>
										<td bgcolor="#ffffff" colspan="3"> </td>
								</tr>
								<tr>
										<td style="FLOAT: left; MARGIN-LEFT: 4px; WIDTH: 100%" nowrap="">
												<a href="http://www.hibernate.org/194.664.html">lazy</a>
												<div twffan="done">
												</div>
										</td>
										<td class="label" style="WIDTH: 150px; COLOR: black" nowrap="">06 Mar 2006, 05:09 
<div twffan="done"></div></td>
										<td class="label" style="COLOR: black" nowrap="">steckemetz 
<div twffan="done"></div></td>
								</tr>
								<tr>
										<td style="PADDING-RIGHT: 4px; PADDING-LEFT: 4px; BACKGROUND: #eeeeee; PADDING-BOTTOM: 4px; PADDING-TOP: 4px" colspan="3">
												<pre>If you have terrible problems with startup time and
do NOT need certain features like:

* proxy objects
* lazy loading

or if you are using the stateless session,
then you can disable lazyness on class level like:

&lt;class name="myClass" table="myTable" lazy="false"&gt;

The default is true and forces byte code generation of
some proxy class which takes a lot of time.
Perhaps some hibernate guru can tell us, which other
features will be disabled by this.</pre>
										</td>
								</tr>
								<tr>
										<td bgcolor="#ffffff" colspan="3"> </td>
								</tr>
								<tr>
										<td style="FLOAT: left; MARGIN-LEFT: 4px; WIDTH: 100%" nowrap="">
												<a href="http://www.hibernate.org/194.724.html">I solve it.</a>
												<div twffan="done">
												</div>
										</td>
										<td class="label" style="WIDTH: 150px; COLOR: black" nowrap="">02 Aug 2006, 00:12 
<div twffan="done"></div></td>
										<td class="label" style="COLOR: black" nowrap="">cm4ever 
<div twffan="done"></div></td>
								</tr>
								<tr>
										<td style="PADDING-RIGHT: 4px; PADDING-LEFT: 4px; BACKGROUND: #eeeeee; PADDING-BOTTOM: 4px; PADDING-TOP: 4px" colspan="3">
												<pre>The Hibernate Configuration module implement is very bad.
I write a module to realize the dynamic loading mapping files.
But other function I can't resolve...

Hibernate Dynamic Module
This project is only a module of Hibernate <a href="http://www.hibernate.org/" target="_blank">http://www.hibernate.org</a> Read
mapping file until insert/update/delete/select the persistent class in
Hibernate.
<a href="http://sourceforge.net/projects/hbn-dyn-mod/" target="_blank">http://sourceforge.net/projects/hbn-dyn-mod/</a></pre>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
<img src ="http://www.blogjava.net/RR00/aggbug/78093.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-10-30 17:22 <a href="http://www.blogjava.net/RR00/articles/78093.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>an easy example for Serializable from web</title><link>http://www.blogjava.net/RR00/articles/78083.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 30 Oct 2006 08:40:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/78083.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/78083.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/78083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/78083.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/78083.html</trackback:ping><description><![CDATA[
		<p>
				<font color="#ff1493">        Configuration configuration=null;<br />        try {<br />            Configuration configurationSerializable = new Configuration();<br />            FileOutputStream fos = new FileOutputStream("serial");<br />            ObjectOutputStream oos = new ObjectOutputStream(fos);<br />            oos.writeObject(configurationSerializable);<br />            oos.flush();<br />            oos.close();<br />        } catch (FileNotFoundException e) {<br />            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.<br />        }<br />        catch (IOException e) {<br />            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.<br />        }</font>
		</p>
		<p>
				<font color="#ff1493">        try {<br />            FileInputStream fis = new FileInputStream("serial");<br />            ObjectInputStream ois = new ObjectInputStream(fis);<br />            configuration = (Configuration) ois.readObject();<br />            ois.close();<br />        } catch (FileNotFoundException e) {<br />            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.<br />        }<br />        catch (IOException e) {<br />            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.<br />        }<br />        catch (ClassNotFoundException e) {<br />            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.<br />        }<br />        if(configuration!=null)<br />        {<br />        SessionFactory sessionFactory = configuration.configure().buildSessionFactory();<br />        Session session = sessionFactory.openSession();<br />        Transaction transaction = session.beginTransaction();<br />        callBack.doing(session);<br />        transaction.commit();<br />        }<br />    }<br /></font>
				<font color="#000000">when will Configuration serialize and why it's some field seted transient?the example will be error because some field transient is null after serialize.</font>
		</p>
<img src ="http://www.blogjava.net/RR00/aggbug/78083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-10-30 16:40 <a href="http://www.blogjava.net/RR00/articles/78083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>inverse in one-to-many mapping</title><link>http://www.blogjava.net/RR00/articles/77190.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 25 Oct 2006 06:23:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/77190.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/77190.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/77190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/77190.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/77190.html</trackback:ping><description><![CDATA[
		<p>when store or delete an 'one-to-many' object to database,it aways update the 'set' defined part.<br />It is wait time in store process and will be error in delete. <br />it is to avoid by set the "inverse = true" .<br /> <br />I will test affect in 'find' and 'update' process.<br /><br />'find' and 'update' don't have any infection with or without 'inverse=true'.<br /><br />the 'inverse' default  set to 'false';</p>
<img src ="http://www.blogjava.net/RR00/aggbug/77190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-10-25 14:23 <a href="http://www.blogjava.net/RR00/articles/77190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>more server run applicatin on the same database will be error!</title><link>http://www.blogjava.net/RR00/articles/76370.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Fri, 20 Oct 2006 05:35:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/76370.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/76370.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/76370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/76370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/76370.html</trackback:ping><description><![CDATA[
		<p align="left">                      <font color="#000000" size="5">if there are more than two server run with the same system code<br />            and call the <font color="#ff1493">save</font> method at the same time ,it will be result of hibernate<br />            error!because hibernate get the max id for ganerator and store it in<br />            cache for next time using.so one server will get the expired id if another<br />            server change the database following.<br />            befroe save object,hibernate will excute this sql after the server start up <font color="#ff1493">once</font>:<br />             Hibernate: select max(ID) from TB_LOG<br />            TB_LOG is my log table.</font></p>
<img src ="http://www.blogjava.net/RR00/aggbug/76370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-10-20 13:35 <a href="http://www.blogjava.net/RR00/articles/76370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate: Understand FlushMode.NEVER</title><link>http://www.blogjava.net/RR00/articles/73976.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 09 Oct 2006 02:08:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/73976.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/73976.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/73976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/73976.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/73976.html</trackback:ping><description><![CDATA[
		<div class="post-content">
				<h2 class="post-title">
						<a title="Permanent Link: Hibernate: Understand FlushMode.NEVER" href="http://www.jroller.com/page/tfenne/?anchor=hibernate_understand_flushmode_never" rel="bookmark">
								<font color="#676e04">Hibernate: Understand FlushMode.NEVER</font>
						</a>
				</h2>
				<p>Posted by tfenne under Java <br /><br /><br />I've <a href="http://forum.hibernate.org/viewtopic.php?t=961626"><font color="#909d73">complained before</font></a> about how the Hibernate documentation doesn't provide much help for those of us dealing with large data sets. The established point of view seems to be that "large amounts of data == batch processing" and "hibernate/java is not the best place for batch processing." Seeing as the system I'm working on currently (a <a href="http://en.wikipedia.org/wiki/DNA"><font color="#909d73">DNA</font></a><a href="http://en.wikipedia.org/wiki/DNA_sequencing"><font color="#909d73">resequencing</font></a><a href="http://en.wikipedia.org/wiki/LIMS"><font color="#909d73">LIMS</font></a>) has a complex data model and very large amounts of OLTP data, I'm at odds with the first piece of accepted knowledge. We deal with large (thousands of objects) complex object webs in memory to implement use cases driven from a user interface in human-time (i.e. non-batch).</p>
				<p>One of the <i>more</i> useful pieces of advice I've seen meted out on the hibernate forums was a trite statement from Gavin to some poor user to "understand FlushMode.NEVER". Well, I've recently had occasion to understand it, and I thought I'd share. To use FlushMode.NEVER you might write something like:</p>
				<pre>session.setFlushMode(FlushMode.NEVER);
</pre>
				<p>This tells the hibernate session that it is not to flush any state changes to the database at all, ever - unless told to do so by the application programmer calling <tt>session.flush()</tt> directly. That's fairly logical, and is useful in it's own right, but why does it have a big impact on performance in some scenarios?</p>
				<p>To explain, let's take a look at a fairly typical use case of mine (if you don't understand the science, don't worry). It involves automatically picking the "best" available <a href="http://en.wikipedia.org/wiki/Polymerase_chain_reaction"><font color="#909d73">PCR primers</font></a> for the <a href="http://en.wikipedia.org/wiki/Gene"><font color="#909d73">genes</font></a>/<a href="http://en.wikipedia.org/wiki/Exon"><font color="#909d73">exons</font></a> being resequenced in an experiment, and goes something like this:</p>
				<ol>
						<li>Find all the exons/targets in the experiment (ranges up to 5000) 
</li>
						<li>Find all the PCR primers that have already been ordered by the experiment, and worked 
</li>
						<li>Find all the PCR primers that are in queue to be ordered by the experiment 
</li>
						<li>Net out the primers against the targets to find what isn't covered 
</li>
						<li>For each un-covered area query for all possible PCR primers in the system 
</li>
						<li>Examine each matching primer and pick the best one for each target 
</li>
						<li>Save the picked PCR primers to the experiment </li>
				</ol>
				<p>Because our domain model is fairly rich, by step 4 we've probably got on the order of 20-30,000 objects in the session! And then each query (it's actually two queries, but that's not so important) in steps 5/6 brings in anywhere from 0 to 20 additional objects. What's interesting though is that while we're pulling in a lot of objects, none of the objects we're loading are getting modified. Only new objects are getting created and saved at the end.</p>
				<p>Back to FlushMode.NEVER then. You might assume that since we're not persisting or changing anything until the last step, changing the flush mode would have little consequence. You'd be wrong of course. In actuality setting flush mode to NEVER at the start of this flow and then flushing manually at the end caused the run time to drop by over half!</p>
				<p>The reason for this is the way hibernate implements dirty checking. Every time you load an object into memory (and don't evict it) the session keeps track of it in case it changes. (Of course, you could evict it - but then any lazy loaded relationships won't be able to load.) So, any time you perform a query, the session <b>iterates over all objects in the session checking dirtiness</b> and flushes any dirty objects to the database. It does this to ensure that all state changes that might affect the query are present in the database before issuing the query to it. That's fine when you have only a few objects in session, but when you have thousands and are performing thousands of queries, it becomes a real drain on performance.</p>
				<p>What I'm yet to understand is exactly why hibernate does it this way. Perhaps it's the developers' belief that improving performance for large data sets isn't worth the additional complexity? What am I talking about? Well, a lot (the vast majority) of the objects that get loaded into memory are proxied by hibernate anyway. These don't <i>need</i> to be dirty checked when queries are made because they could actively be flagged as dirty when changes are made through the proxy, and added directly to a dirty list. It would seem to me that if hibnerate always returned proxied instances - even on non-lazy loads - this problem could practically disappear. There's still the case when someone persists a new object and then tries to modify it without replacing their reference with a newly proxified reference- but even if those instances were tracked the old way, it would hardly affect performance in most use cases like this.</p>
				<p>Anyway, the moral of the story is this: in use cases with lots of reading/querying and lots of objects in session you should use FlushMode.NEVER as long as you're not modifying data that will affact your queries. Example psuedo-code is below:</p>
				<pre>FlushMode previous = session.getFlushMode();
session.flush(); // who know's what been done till now
session.setFlushMode(FlushMode.NEVER);
// Do some querying
// Do some more querying
// Really load up that session
// Execute a few more queries
// Write back to some tables
session.flush();
session.setFlushMode(previous);
</pre>
				<!-- <p class="post-info">
    <?php wp_link_pages(); ?>
    </p>-->
				<!--
    <?php trackback_rdf(); ?>
    -->
				<div class="post-footer"> </div>
		</div>
		<!--
				<?php comments_template(); // Get wp-comments.php template ?>
-->
		<div class="comments" id="comments">
				<div class="comments-head">Comments:</div>
				<br />
				<!-- comment: ff8080810d16e6d1010d1b306ac70cfc -->
				<div class="comment" id="comment1">session.setReadOnly() and instrumentation of classes will help you get close to what you want. <br /><br />a simple dirty flag/setting is not enough to guarantee consistency. 
<p class="comment-details">Posted by <a title="212.249.12.130" href="mailto:max.andersen%40jboss.com"><font color="#909d73">Max Rydahl Andersen</font></a> on August 17, 2006 at 04:12 AM EDT <a class="entrypermalink" title="comment permalink" href="http://www.jroller.com/page/tfenne?entry=hibernate_understand_flushmode_never#comment1"><font color="#909d73">#</font></a></p></div>
		</div>
<img src ="http://www.blogjava.net/RR00/aggbug/73976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-10-09 10:08 <a href="http://www.blogjava.net/RR00/articles/73976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mappings.setDefaultLazy(dlNode == null || dlNode.getValue().equals("true"));</title><link>http://www.blogjava.net/RR00/articles/73081.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Sat, 30 Sep 2006 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/73081.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/73081.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/73081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/73081.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/73081.html</trackback:ping><description><![CDATA[
		<font color="#ff0000">1st:</font>   mappings.setDefaultLazy(dlNode == null || dlNode.getValue().equals("true"));<br /><font color="#ff0000">2ed:</font>  mappings.setAutoImport((aiNode == null) ? true : "true".equals(aiNode.getValue()));<br /><br />the first is seems a bit more effective than the second but less readable ,hence we choose the second!<br />bad programmer write code readed by machine and by contraries good programmer write code readed by human!<img src ="http://www.blogjava.net/RR00/aggbug/73081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-30 18:07 <a href="http://www.blogjava.net/RR00/articles/73081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>New in Hibernate 3: Criteria API enhancements</title><link>http://www.blogjava.net/RR00/articles/72800.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Fri, 29 Sep 2006 06:30:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/72800.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/72800.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/72800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/72800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/72800.html</trackback:ping><description><![CDATA[
		<div class="post">
				<h3 class="storytitle" id="post-68">  Projection, aggregation, subselects, detatched criterias - its all there in the Hibernate 3 Criteria API. Let me show you some examples, starting with the new projection API. Suppose we have a User class and only want to query for its username:</h3>
				<div class="storycontent">
						<pre class="code">session.createCriteria(User.class)
    . setProjection(Projection.property(\"username\"))
    .list();
</pre>
						<p>would do exactly what we want. Of course we can also use projection for multiple properties, and combine it with all the other existing features of the Criteria API. For example</p>
						<pre class="code">session.createCriteria(User.class).setProjection(
    Projections.propertyList()
        .add(Projection.property(\"firstname\"))
        .add(Projection.property(\"lastname\"))
    )
    .add(Restriction.gt(\"age\", 25))
    .list();
</pre>
						<p>would give us the firstnames and lastnames of all users with an age larger than 25. We can also use aggregation - if we want to count the number of users with lastname “Black”, we can use</p>
						<pre class="code">session.createCriteria(User.class)
    .setProjection(Projections.rowCount())
    .add(Restriction.eq(\"lastname\", \"Black\"))
    .list();
</pre>
						<p>we can even use grouping and projection on associated objects:</p>
						<pre class="code">session.createCriteria(User.class)
    .createAlias(\"roles\", \"r\")
    .setProjection( Projections.projectionList()
        .add(Projection.groupProperty(\"r.name\"))
        .add(Projection.rowCount())
    )
    .list();
</pre>
						<p>This criteria query gives us the number of users, grouped by role names. With the new Criteria API extensions, you can also construct “detatched criteria” instances, which you can build outside of the session scope, and later use for querying. For example</p>
						<pre class="code">DetatchedCriteria dc = DetatchedCriteria.forClass(User.class)
    .add(Property.forName(\"firstname\").eq(\"John\")
    .setProjection(Property.forName(\"age\").min());
	
Session session = sessionFactory.openSession();
	
dc.getExecutableCriteria(session).list();
</pre>
						<p>would give use the age of the youngest user named John. You can even use the detatched criteria for building subqueries. For example </p>
						<pre class="code">DetatchedCriteria dc = DetatchedCriteria.forClass(User.class)
    .add(Property.forName(\"firstname\").eq(\"John\")
    .setProjection(Property.forName(\"age\").min());
	
session.createCriteria(User.class)
    .add(Subqueries.propertyEq(\"age\", dc))
    .list();
</pre>
						<p>would give us all Users which have the same age as the youngest User named John.</p>
						<p>Alltogether the new H3 criteria API now is featurewise just as powerful as the HQL query language. If you want to try and experiment with it, download the newest Hibernate 3 beta from <a href="http://www.hibernate.org/">the Hibernate website</a></p>
				</div>
				<!-- end STORYCONTENT -->
				<div class="feedback">
				</div>
				<!-- end FEEDBACK -->
				<!--

	<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
	    xmlns:dc="http://purl.org/dc/elements/1.1/"
	    xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
		<rdf:Description rdf:about="http://www.gloegl.de/blog/archives/hibernate-3-criteria-api-enhancements/"
    dc:identifier="http://www.gloegl.de/blog/archives/hibernate-3-criteria-api-enhancements/"
    dc:title="New in Hibernate 3: Criteria API enhancements"
    trackback:ping="http://www.gloegl.de/blog/archives/hibernate-3-criteria-api-enhancements/trackback/" />
</rdf:RDF>
	-->
		</div>
		<!-- end POST -->
<img src ="http://www.blogjava.net/RR00/aggbug/72800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-29 14:30 <a href="http://www.blogjava.net/RR00/articles/72800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>refill of if-else or switch</title><link>http://www.blogjava.net/RR00/articles/72633.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 28 Sep 2006 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/72633.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/72633.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/72633.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/72633.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/72633.html</trackback:ping><description><![CDATA[strategy pattern and state pattern  are good way for replacing if-else or switch.strategy pattern is for choose appropriate arithmetic,state is for automatically changing state,single factory pattern for create appropriate instance and abstract factory    choose appropriate  instance by programmer.<img src ="http://www.blogjava.net/RR00/aggbug/72633.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-28 17:30 <a href="http://www.blogjava.net/RR00/articles/72633.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mappings for many properties</title><link>http://www.blogjava.net/RR00/articles/71802.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 25 Sep 2006 09:39:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/71802.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/71802.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/71802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/71802.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/71802.html</trackback:ping><description><![CDATA[in class Configuration ,there is many properties to init.see how hibernate deal with all the properties.it use class Mappings to include all the proterties which had a constructor needed all the proterties.as we know,Configuration deal with the hibernate.cfg.xml and HbmBinder with the *.hbm.xml,but all the properties are stored in Configuration then used to build<br />SessionFactory.How Configuration get the properties analyzed in HbmBinder .The bridge is the Mappings .Configuration <br />had many private property fields,e.g.  classes,collections,tables,imports and so on.when call HbmBinder to work,Configuration first createMappings with its property fields then pass the Mappings  to the HbmBinder .In HbmBinder ,what Mappings   had done is also the  Configuration 's field done.<br /><br />e.g. Configuration  has a field "imports" ,it gone with the Mappings as a parameter in Mappings constructor to HbmBinder .<br />in HbmBinder class ,HbmBinder use Mappings .addImport() to operate it and at the same time point to the Configuration's "imports".This is correlative to java's clone mechanism.<br /><br />this gives us a exquisite way to deal with more properties among several class.<br /><br /><br /><br /><img src ="http://www.blogjava.net/RR00/aggbug/71802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-25 17:39 <a href="http://www.blogjava.net/RR00/articles/71802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>about "entity-name"</title><link>http://www.blogjava.net/RR00/articles/71680.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 25 Sep 2006 03:12:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/71680.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/71680.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/71680.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/71680.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/71680.html</trackback:ping><description><![CDATA[
		<p>in POJO model,PersistentClass use "entity-name" or "name" to set the EntityName.it seems redundant because "name" is content util I find theDynamic models. in the mapping file, an <tt class="literal">entity-name</tt> has to be declared instead of (or in addition to) a class name. so the two name strategy is for two case.</p>
<img src ="http://www.blogjava.net/RR00/aggbug/71680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-25 11:12 <a href="http://www.blogjava.net/RR00/articles/71680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ListIterator in hibernate</title><link>http://www.blogjava.net/RR00/articles/69392.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 13 Sep 2006 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/69392.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/69392.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/69392.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/69392.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/69392.html</trackback:ping><description><![CDATA[ArrayList orderedFromElements = new ArrayList();<br />  ListIterator liter = fromClause.getFromElements().listIterator( fromClause.getFromElements().size() );<br />  while ( liter.hasPrevious() ) {<br />            log.debug("add previous");<br />            orderedFromElements.add( liter.previous() );<br />  }<img src ="http://www.blogjava.net/RR00/aggbug/69392.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-13 16:01 <a href="http://www.blogjava.net/RR00/articles/69392.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tips &amp; Tricks</title><link>http://www.blogjava.net/RR00/articles/68961.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 11 Sep 2006 07:01:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/68961.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/68961.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/68961.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/68961.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/68961.html</trackback:ping><description><![CDATA[Tips &amp; Tricks
<div></div><p>You can count the number of query results without actually returning them: </p><pre class="programlisting">( (Integer) session.iterate("select count(*) from ....").next() ).intValue()</pre><p>To order a result by the size of a collection, use the following query: </p><pre class="programlisting">select usr.id, usr.name
from User as usr 
    left join usr.messages as msg
group by usr.id, usr.name
order by count(msg)</pre><p>If your database supports subselects, you can place a condition upon selection size in the where clause of your query: </p><pre class="programlisting">from User usr where size(usr.messages) &gt;= 1</pre><p>If your database doesn't support subselects, use the following query: </p><pre class="programlisting">select usr.id, usr.name
from User usr.name
    join usr.messages msg
group by usr.id, usr.name
having count(msg) &gt;= 1</pre><p>As this solution can't return a <tt class="literal">User</tt> with zero messages because of the inner join, the following form is also useful: </p><pre class="programlisting">select usr.id, usr.name
from User as usr
    left join usr.messages as msg
group by usr.id, usr.name
having count(msg) = 0</pre><p>Properties of a JavaBean can be bound to named query parameters: </p><pre class="programlisting">Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
q.setProperties(fooBean); // fooBean has getName() and getSize()
List foos = q.list();</pre><p>Collections are pageable by using the <tt class="literal">Query</tt> interface with a filter: </p><pre class="programlisting">Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();</pre><p>Collection elements may be ordered or grouped using a query filter: </p><pre class="programlisting">Collection orderedCollection = s.filter( collection, "order by this.amount" );
Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );</pre><p>You can find the size of a collection without initializing it: </p><pre class="programlisting">( (Integer) session.iterate("select count(*) from ....").next() ).intValue();</pre><img src ="http://www.blogjava.net/RR00/aggbug/68961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-11 15:01 <a href="http://www.blogjava.net/RR00/articles/68961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>get query list's size</title><link>http://www.blogjava.net/RR00/articles/68960.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 11 Sep 2006 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/68960.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/68960.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/68960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/68960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/68960.html</trackback:ping><description><![CDATA[
		<span class="postbody">
				<font size="2">There are several approaches to get the size of a list. <br />1. select cout(*) is ok, but forces you to a new select statement <br />2. try using a <a href="articles/68961.html"><strong>filter </strong></a><br />3. use scrollable resultsets: <br /></font>
		</span>
		<table cellspacing="1" cellpadding="3" width="100%" align="center" border="0">
				<tbody>
						<tr>
								<td class="code">ScrollableResult scroll = query.scroll(); <br />scroll.afterLast(); <br />int size = scroll.rowNumber(); <br />scroll.beforeFirst();</td>
						</tr>
				</tbody>
		</table>
		<span class="postbody">
				<br />
				<br />
				<font size="2">Which approach ist best, depends on your select.</font>
		</span>
		<span class="gensmall">
		</span>
<img src ="http://www.blogjava.net/RR00/aggbug/68960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-11 15:00 <a href="http://www.blogjava.net/RR00/articles/68960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate3.1.3:polymorphism="explicit"</title><link>http://www.blogjava.net/RR00/articles/66879.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 31 Aug 2006 07:31:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66879.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66879.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66879.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66879.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66879.html</trackback:ping><description><![CDATA[it seems only use in <font color="#ff1493">Table Per Concrete Class,</font><font color="#000000">if a class set polymorphism="implicit",when select from his child class or parent class,the clall can be selected.this is the default value of the 'polymorphism'.else if the class set polymorphism="explicit",only select from it's name then it can be select ,selecting  from his child class or parent class don't return it.</font><img src ="http://www.blogjava.net/RR00/aggbug/66879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-31 15:31 <a href="http://www.blogjava.net/RR00/articles/66879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Herbiernate3.1.3:Set</title><link>http://www.blogjava.net/RR00/articles/66874.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 31 Aug 2006 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66874.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66874.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66874.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66874.html</trackback:ping><description><![CDATA[
		<p>Set in hibernate sort all elements by cast the field set to <font color="#ff1493">org.hibernate.type.SortedSetType</font>,which wrap the  <font color="#ff1493">java.util.SortedSet when persite </font><font color="#000000">In the </font><font color="#000000">SortedSetType.</font><font color="#ee82ee">wrap(SessionImplementor session, Object collection)<font color="#000000">.<br />it  </font></font><font color="#ff1493">return new PersistentSortedSet( session, (java.util.SortedSet) collection ); </font><font color="#000000">so if you wanted the set sortable,<br />must use the class that implements the </font><font color="#ff1493">java.util.SortedSet ,</font><font color="#000000">and in java.util package,<font color="#ff0000">TreeSet</font>  is  validated.<br />if use HashSet ,you will get error report always in insert time.</font></p>
<img src ="http://www.blogjava.net/RR00/aggbug/66874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-31 15:26 <a href="http://www.blogjava.net/RR00/articles/66874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Query Cache</title><link>http://www.blogjava.net/RR00/articles/66716.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 30 Aug 2006 12:16:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66716.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66716.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66716.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66716.html</trackback:ping><description><![CDATA[It seems it can't set in xml,but set in application like this: <font color="#ff0000">query.setCacheable(); </font><font color="#000000">This cache's scope like Second-level cache,live among SessionFaction lifecycle( work in all sessionFactory lifecycle).it means even open a new session after another close,it also validate.The cache will be evict when the object changed.if the  associated object changed,the Query cache will not work.<br /><br />if the first queryed obejct update ,second query object also use query cache and get the updated value,just like <br />Second-Level cache.</font><img src ="http://www.blogjava.net/RR00/aggbug/66716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-30 20:16 <a href="http://www.blogjava.net/RR00/articles/66716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cache usage</title><link>http://www.blogjava.net/RR00/articles/66711.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 30 Aug 2006 10:28:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66711.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66711.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66711.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66711.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66711.html</trackback:ping><description><![CDATA[it must set <font color="#006400">&lt;cache usage="read-write"/&gt;</font> in class after put the <font color="#008000">eccache.xml</font> in the classpath,else the session-level cache don't work !<br /><br />Hibernate Version:3.1.3<img src ="http://www.blogjava.net/RR00/aggbug/66711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-30 18:28 <a href="http://www.blogjava.net/RR00/articles/66711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Object in session</title><link>http://www.blogjava.net/RR00/articles/66709.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 30 Aug 2006 10:18:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66709.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66709.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66709.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66709.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66709.html</trackback:ping><description><![CDATA[
		<p>   an object first loaded by session(eg,session.load(...,..)),if session don't close,the following load will return the same object.this means that if the first loaded object change,the following loaded object also == the first object ,not the refresh object from database!<br /><br /><font color="#a52a2a">compositeIdUser = (CompositeIdUser) session.load(CompositeIdUser.class, compositeIdUser);<br />compositeIdUser.setAge(new Integer(1133883)); //<font color="#0000ff">change the age</font><br /> compositeIdUser = (CompositeIdUser) session.load(CompositeIdUser.class, compositeIdUser);<br /></font> <font color="#a52a2a"><font color="#ff0000">compositeIdUser.getAge will equals 1133883;</font> //</font><font color="#0000ff">the second loaded object == the first!</font>     <br /><br />in two session with session-level cache ,if the first object change and saveOrUpdate ,the second object don't select from database and still use cache.because when the first object change and saveOrUpdate ,the cache also update to the latest version.</p>
<img src ="http://www.blogjava.net/RR00/aggbug/66709.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-30 18:18 <a href="http://www.blogjava.net/RR00/articles/66709.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Composite-Id</title><link>http://www.blogjava.net/RR00/articles/66671.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Wed, 30 Aug 2006 07:36:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66671.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66671.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66671.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66671.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66671.html</trackback:ping><description><![CDATA[   Composite-Id 中以多个filed为主键或以一个类为主键（主键所在的类必须implements Serializable），it seems no need for class overwriting hascode(),equals().maybe the hibernate use the primary key to distinguish the object.<br />Hibernate Version: 3.1.3<img src ="http://www.blogjava.net/RR00/aggbug/66671.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-30 15:36 <a href="http://www.blogjava.net/RR00/articles/66671.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>many-to-many delete</title><link>http://www.blogjava.net/RR00/articles/66413.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Tue, 29 Aug 2006 06:02:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66413.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66413.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66413.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66413.html</trackback:ping><description><![CDATA[
		<span class="postbody">
				<font size="2">some person say:<br /><br />When using a many-to-many association cascade="all", cascade="delete", and cascade="all-delete-orphans" aren't meaningful. That's because you might delete an instance that can have other parents pointing to it. <br /><br />If you want to delete rows from the association table (rel_houses_owners) then I would suggest using two one-to-many relationships instead of many-to-many. <br /><br />You would need one-to-many from owners to house_owners and many-to-one from house_owners to owners. This will allow you to cascade deletes in owner to house_owners without deleting the owner. <br /><br />Use of many-to-many often leads to the solution described above and is hence discouraged.</font>
		</span>
		<span class="gensmall">
		</span>
<img src ="http://www.blogjava.net/RR00/aggbug/66413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-29 14:02 <a href="http://www.blogjava.net/RR00/articles/66413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>one-to-may</title><link>http://www.blogjava.net/RR00/articles/66191.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 28 Aug 2006 07:18:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66191.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66191.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66191.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66191.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66191.html</trackback:ping><description><![CDATA[ CREATE TABLE more_specialties (<br />            id INTEGER NOT NULL IDENTITY PRIMARY KEY<br />            ,name varchar(50)<br />            , specialty_id INTEGER<br />          <font color="#a52a2a">  &lt;!--if is not null,on one-to-many saveing object will encounter <font color="#cc0000">error</font> --&gt;<br /></font>            );<br /><br />why ?see the following debug report:<br /><br />...<br /><font color="#a52a2a">DEBUG - AbstractBatcher.log(366) | getSQL(sql) = insert into more_specialties (name, id) values (?, null)<br /></font>...<br /><font color="#a52a2a">DEBUG - AbstractBatcher.log(366) | getSQL(sql) = update more_specialties set specialty_id=? where id=?</font><br />...<br /><br />it is clearly that it first insert null values to the specialty_id  the update it.and in business logic, specialty_id should be null<br /><br />it use the <br /><br /><font color="#a52a2a"> &lt;set name="moreSpecialties" table="more_specialties" cascade="all"&gt;<br />            &lt;key column="specialty_id"  /&gt;<br />            &lt;one-to-many class="MoreSpecialty" /&gt;<br />        &lt;/set&gt;<br /><br /><font color="#000000">and in the one-class <font color="#a52a2a">Specialty </font><font color="#000000">of </font>one-to-many  </font><font color="#000000">,initl the Set,else it will be an error of java.lang.NullPointerException!<br /></font>private Set moreSpecialties=new HashSet();<br /><br /></font><img src ="http://www.blogjava.net/RR00/aggbug/66191.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-28 15:18 <a href="http://www.blogjava.net/RR00/articles/66191.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>one-to-one</title><link>http://www.blogjava.net/RR00/articles/66162.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 28 Aug 2006 05:45:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/66162.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/66162.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/66162.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/66162.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/66162.html</trackback:ping><description><![CDATA[
		<font color="#000000">for example</font>
		<br />
		<br />
		<br />
		<div style="MARGIN-LEFT: 40px; FONT-FAMILY: Courier New,Courier,monospace">
				<span style="FONT-WEIGHT: bold">CREATE TABLE user (</span>
				<br style="FONT-WEIGHT: bold" />
				<span style="FONT-WEIGHT: bold">    id INT(11) NOT NULL auto_increment PRIMARY KEY,</span>
				<br style="FONT-WEIGHT: bold" />
				<span style="FONT-WEIGHT: bold">    name VARCHAR(100) NOT NULL default ''</span>
				<span style="FONT-WEIGHT: bold">
				</span>
				<br style="FONT-WEIGHT: bold" />
				<span style="FONT-WEIGHT: bold">);</span>
				<br style="FONT-WEIGHT: bold" />
				<br style="FONT-WEIGHT: bold" />
				<span style="FONT-WEIGHT: bold">CREATE TABLE room (</span>
				<br style="FONT-WEIGHT: bold" />
				<span style="FONT-WEIGHT: bold">    id INT(11) NOT NULL auto_increment PRIMARY KEY,</span>
				<br style="FONT-WEIGHT: bold" />
				<span style="FONT-WEIGHT: bold">    address VARCHAR(100) NOT NULL default ''</span>
				<br style="FONT-WEIGHT: bold" />
				<span style="FONT-WEIGHT: bold">);</span>
				<br />
				<br />
		</div>
		<p style="MARGIN-LEFT: 40px; FONT-FAMILY: Courier New,Courier,monospace">
				<br />User.hbm.xml </p>
		<div style="MARGIN-LEFT: 40px; FONT-FAMILY: Courier New,Courier,monospace">
				<ul>
						<li>
								<pre>
										<font color="#a52a2a">&lt;?xml version="1.0" encoding="utf-8"?&gt; <br />&lt;!DOCTYPE hibernate-mapping <br />    PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <br />    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt; <br /><br />&lt;hibernate-mapping&gt; <br /><br />    &lt;class name="onlyfun.caterpillar.User" table="user"&gt; <br />        &lt;id name="id" column="id" type="java.lang.Integer"&gt; <br />            &lt;generator class="native"/&gt; <br />        &lt;/id&gt; <br /><br />        &lt;property name="name" column="name" type="java.lang.String"/&gt; <br /><br /><span style="FONT-WEIGHT: bold">        &lt;one-to-one name="room" </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">                    class="onlyfun.caterpillar.Room"</span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">                    cascade="all"/&gt;</span><br />    &lt;/class&gt; <br /><br />&lt;/hibernate-mapping&gt;</font>
								</pre>
								<br />
								<ul>
										<li>Room.hbm.xml </li>
								</ul>
								<pre>
										<font color="#a52a2a">&lt;?xml version="1.0" encoding="utf-8"?&gt; <br />&lt;!DOCTYPE hibernate-mapping <br />    PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <br />    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt; <br /><br />&lt;hibernate-mapping&gt; <br /><br />    &lt;class name="onlyfun.caterpillar.Room" table="room"&gt; <br />        &lt;id name="id" column="id"&gt; <br /><span style="FONT-WEIGHT: bold">            &lt;generator class="foreign"&gt; </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">                &lt;param name="property"&gt;user&lt;/param&gt;</span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">            &lt;/generator&gt;</span><br />        &lt;/id&gt; <br /><br />        &lt;property name="address" <br />                  column="address" <br />                  type="java.lang.String"/&gt; <br /><br /><span style="FONT-WEIGHT: bold">        &lt;one-to-one name="user"</span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">                    class="onlyfun.caterpillar.User"</span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">                    constrained="true"/&gt;</span><br />    &lt;/class&gt; <br /><br />&lt;/hibernate-mapping&gt;</font>
								</pre>
						</li>
				</ul>
		</div>
		<pre>
				<font color="#a52a2a">
						<font color="#000000">java:</font>
						<br />
						<br />
						<br />
						<br />
						<br />
						<br />
						<br />
						<br />
						<div style="MARGIN-LEFT: 40px">
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">
										<br />
										<br />
										<br />User user1 = new User();</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.setName("bush"); </span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Room room1 = new Room(); </span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">room1.setAddress("NTU-M8-419");</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.setRoom(room1);</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">room1.setUser(user1);</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx = session.beginTransaction();</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"> </span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.save(user1);</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx.commit();</span>
								<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
								<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span>
								<br />
						</div>
						<br />
						<br />
						<br />
						<br />
						<br />
						<br />
						<font color="#000000">the above is run right,but if the following :<br /></font>
						<br />
						<br />
						<strong>User user1 = new User();<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  user1.setName("bush"); </span></strong>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  Room room1 = new Room(); </span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  room1.setAddress("NTU-M8-419");</span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  user1.setRoom(room1);</span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  room1.setUser(user1);<br /></span>
						<br />
						<br />
						<br />
						<strong>User user2 = new User();<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  user2.setName("bush"); <br /></span></strong>
						<br />
						<br />
						<font color="#0000ff"> //the new column point to the same room1 and no errors </font>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<br />
						<strong>user2.setRoom(room1);</strong>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  Session session = sessionFactory.openSession();</span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  Transaction tx = session.beginTransaction();</span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"> </span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  session.save(user1); <br /><font color="#0000ff"> //save</font><br /></span>
						<br />
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  session.save(user2);<br />      </span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  tx.commit();</span>
						<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" />
						<span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">  session.close();<br /></span>
						<br />
						<br />
						<br />
				</font>
				<font color="#0000ff">is "one-to-one" in hibernate just for creating  a foreign key for another table?<br />did it make any restriction between the two tables.</font>
		</pre>
<img src ="http://www.blogjava.net/RR00/aggbug/66162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-28 13:45 <a href="http://www.blogjava.net/RR00/articles/66162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate3 : org.hibernate.cfg.Configuration解析</title><link>http://www.blogjava.net/RR00/articles/64886.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 21 Aug 2006 13:08:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/64886.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/64886.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/64886.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/64886.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/64886.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="mso-spacerun: yes"> </span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第一次写文章，不好的地方，请口下留情哈。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
						<span style="COLOR: blue">org.hibernate.cfg.Configurations</span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据</span>
				<span lang="EN-US">xml</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件配置整个工作过程中所需要的参数。一般</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们会用</span>
				<span lang="EN-US" style="COLOR: blue">Configuration cfg = new Configuration().configure();</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">创建一个配置类。那么，这句话到底做了什么呢？</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首先，</span>
				<span lang="EN-US" style="COLOR: blue">new Configuration()</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会做些什么呢？我们来看他的源码：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">   </span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes"> </span>
						<span style="COLOR: blue">protected Configuration(SettingsFactory settingsFactory) {<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>System.out.println("Configuration(SettingsFactory settingsFactory)");<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>this.settingsFactory = settingsFactory;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>reset();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">    </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">//</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">默认构造函数，先</span>
				<span lang="EN-US" style="COLOR: blue">new SettingsFactory()</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后调用</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">//<span style="COLOR: blue">protected Configuration(SettingsFactory settingsFactory)</span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">    </span>
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">public Configuration() {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>this(new SettingsFactory());<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt">
				<span lang="EN-US" style="COLOR: blue">}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt">
				<span lang="EN-US" style="COLOR: blue">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">reset()</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化了很多变量，感兴趣的可以去看源代码，没有什么特别的地方。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接着，调用</span>
				<span lang="EN-US" style="COLOR: blue">configure()</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法！</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">public Configuration configure() throws HibernateException {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>configure("/hibernate.cfg.xml");<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>return this;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt">
				<span lang="EN-US" style="COLOR: blue">}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 10.5pt; mso-char-indent-count: 1.0">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以看出，默认使用</span>
				<span lang="EN-US" style="COLOR: blue">hibernate.cfg.xml</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，如果想用自定义的文件，可以调用</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">configure(“….xml”)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">public Configuration configure(String resource) throws HibernateException {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>log.debug("configuring from resource: " + resource);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>InputStream stream = getConfigurationInputStream(resource);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>return doConfigure(stream, resource);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21.75pt">
				<span lang="EN-US" style="COLOR: blue">}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据</span>
				<span lang="EN-US" style="COLOR: blue">getConfigurationInputStream(resource)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">得到文件流，</span>
				<span lang="EN-US" style="COLOR: blue">getConfigurationInputStream(resource)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调用</span>
				<span lang="EN-US" style="COLOR: blue">ConfigHelper.getResourceAsStream(resource)</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
				<span lang="EN-US" style="COLOR: blue">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">public static InputStream getResourceAsStream(String resource) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>String stripped = resource.startsWith("/") ? <o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 4">                            </span>resource.substring(1) : resource;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>InputStream stream = null; <o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>ClassLoader classLoader = Thread.currentThread().getContextClassLoader();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>if (classLoader!=null) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 3">                     </span>stream = classLoader.getResourceAsStream( stripped );<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-tab-count: 2">              </span>}</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">//</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里的代码可能应该是</span>
				<span lang="EN-US" style="COLOR: blue">stream = Environment.class.getResourceAsStream( resource );<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-tab-count: 2">              </span>
						<span style="COLOR: blue">if ( stream == null ) {<o:p></o:p></span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 3">                     </span>Environment.class.getResourceAsStream( resource );<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>if ( stream == null ) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 3">                     </span>stream = Environment.class.getClassLoader().getResourceAsStream( stripped );<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>if ( stream == null ) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 3">                     </span>throw new HibernateException( resource + " not found" );<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 2">              </span>return stream;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-tab-count: 1">       </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后</span>
				<span lang="EN-US" style="COLOR: blue">doConfigure(stream, resource)</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
				<span lang="EN-US" style="COLOR: blue">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">org.dom4j.Document doc;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>try {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">            </span>List errors = new ArrayList();<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">            </span>SAXReader saxReader = xmlHelper.createSAXReader(resourceName, errors, entityResolver);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">            </span>doc = saxReader.read(new InputSource(stream));<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">            </span>if (errors.size() != 0) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">                </span>throw new MappingException(<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">                        </span>"invalid configuration",<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">                        </span>(Throwable) errors.get(0)<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">                </span>);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">            </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">entityResolver</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在初始值为</span>
				<span lang="EN-US" style="COLOR: blue">entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER</span>
				<span lang="EN-US">;</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>
				<span lang="EN-US" style="COLOR: blue">reset()</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的时候设置的。</span>
				<span lang="EN-US" style="COLOR: blue">XMLHelper.DEFAULT_DTD_RESOLVE</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>
				<span lang="EN-US" style="COLOR: blue">XMLHelper</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">默认是</span>
				<span lang="EN-US" style="COLOR: blue">XMLHelper.DEFAULT_DTD_RESOLVER= new DTDEntityResolver()</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">；</span>
				<span lang="EN-US" style="COLOR: blue">DTDEntityResolver</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是用来加载</span>
				<span lang="EN-US">dtd</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件的。别跟我说你不知道</span>
				<span lang="EN-US">dtd</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是什么东西？它有</span>
				<span lang="EN-US">3</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">种加载方式：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">1．<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件路径以</span>
				<span lang="EN-US">
						<a href="http://hibernate.sourceforge.net/">http://hibernate.sourceforge.net/</a>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开头的文件，如</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<a href="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd</a>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它会把</span>
				<span lang="EN-US">
						<a href="http://hibernate.sourceforge.net/">http://hibernate.sourceforge.net</a>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">去掉，加上</span>
				<span lang="EN-US" style="COLOR: blue">org/hibernate/</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，文件路径为</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">org/hibernate/<a href="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">hibernate-configuration-3.0.dtd</a></span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，然后加载这个文件。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">2.<span style="FONT: 7pt 'Times New Roman'">       </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件路径以</span>
				<span lang="EN-US">file://</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开头的文件，如</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<a href="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
								<span style="COLOR: windowtext; TEXT-DECORATION: none; text-underline: none">
										<span style="mso-spacerun: yes"> </span>
								</span>file://hibernate-configuration-3.0.dtd</a>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它会把</span>
				<span lang="EN-US">file://</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">去掉，路径为</span>
				<span lang="EN-US">
						<a href="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">hibernate-configuration-3.0.dtd</a>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，然后加载这个文件。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">3.</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果没有以上</span>
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">种情况，则直接加载。就是路径名没有修改过。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">整个过程在</span>
				<span lang="EN-US" style="COLOR: blue">public InputSource resolveEntity(String publicId, String systemId)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中实现。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">systemId</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是</span>
				<span lang="EN-US" style="COLOR: blue">dtd</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的路径。大家可以去看看</span>
				<span lang="EN-US" style="COLOR: blue">SAXReader</span>
				<span lang="EN-US">
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类自带的</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">protected static class SAXEntityResolver</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，比较比较。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">
						</span>
				</span> </p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在得到</span>
				<span lang="EN-US" style="COLOR: blue">doc</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">            </span>
						<span style="COLOR: blue">doc = saxReader.read(new InputSource(stream));<o:p></o:p></span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后，调用</span>
				<span lang="EN-US" style="COLOR: blue">protected Configuration doConfigure(org.dom4j.Document doc)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，这个函数主要是根据</span>
				<span lang="EN-US" style="COLOR: blue">doc</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的到配置参数，然后存到</span>
				<span lang="EN-US" style="COLOR: blue">properties</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">先是设置</span>
				<span lang="EN-US" style="COLOR: blue">session-factory</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名字：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 42pt; mso-char-indent-count: 4.0">
				<span lang="EN-US" style="COLOR: blue">Element sfNode = doc.getRootElement().element("session-factory");<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>String name = sfNode.attributeValue("name");<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>if (name != null) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">             </span>//</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">保存到</span>
				<span lang="EN-US" style="COLOR: blue">properties</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中！</span>
				<span lang="EN-US" style="COLOR: blue">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">            </span>properties.setProperty(Environment.SESSION_FACTORY_NAME, name);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">        </span>}<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后是</span>
				<span lang="EN-US" style="COLOR: blue">addProperties(sfNode)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，把</span>
				<span lang="EN-US" style="COLOR: blue">&lt;property name=" "&gt; &lt;/property&gt;</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">保存到</span>
				<span lang="EN-US" style="COLOR: blue">properties</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 63pt; mso-char-indent-count: 6.0">
				<span lang="EN-US" style="COLOR: blue">//</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这句话估计又是多余的</span>
				<span lang="EN-US" style="COLOR: blue">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 63pt; mso-char-indent-count: 6.0">
				<span lang="EN-US" style="COLOR: blue">properties.setProperty(name, value);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 63pt; mso-char-indent-count: 6.0">
				<span lang="EN-US" style="COLOR: blue">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">           </span>
						<span style="mso-spacerun: yes"> </span>if (!name.startsWith("hibernate")) {<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">                </span>properties.setProperty("hibernate." + name, value);<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">
						<span style="mso-spacerun: yes">            </span>}</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接着调用了</span>
				<span lang="EN-US" style="COLOR: blue">parseSessionFactory(sfNode, name)</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，把</span>
				<span lang="EN-US" style="COLOR: blue">mapping</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span lang="EN-US" style="COLOR: blue">class-cache</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span lang="EN-US" style="COLOR: blue">collection-cache</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span lang="EN-US" style="COLOR: blue">listener </span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，</span>
				<span lang="EN-US" style="COLOR: blue">event</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等配置保存。到底它保存到哪，我也不全知道，只看了</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">protected void parseMappingElement(Element subelement, String name),</span>
				<span style="COLOR: blue; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据配置加载了</span>
				<span lang="EN-US" style="COLOR: blue">mapping</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的文件，最后使用</span>
				<span lang="EN-US" style="COLOR: blue">HbmBinder : public static void bindRoot(Document doc, Mappings mappings, java.util.Map inheritedMetas)</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">保存。</span>
				<span lang="EN-US" style="COLOR: blue">bindRoot</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是对</span>
				<span lang="EN-US" style="COLOR: blue">mapping</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的</span>
				<span lang="EN-US" style="COLOR: blue">xml</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件进行解析。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US" style="COLOR: blue">HbmBinder</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>
				<span lang="EN-US" style="COLOR: blue">Configuration</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都有</span>
				<span lang="EN-US">2000</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">行以上的代码，在</span>
				<span lang="EN-US" style="COLOR: blue">Hibernate</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中有很重要的地位。</span>
				<span lang="EN-US" style="COLOR: blue">Configuration</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用</span>
				<span lang="EN-US" style="COLOR: blue">.cfg.xml</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，而</span>
				<span lang="EN-US" style="COLOR: blue">HbmBinder</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">则使用了</span>
				<span lang="EN-US" style="COLOR: blue">.hbm.xml</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-tab-count: 2">              </span>extractRootAttributes( hmNode, mappings )</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据</span>
				<span lang="EN-US">&lt;hibernate-mapping&gt;</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的配置，把分析的结果存入</span>
				<span lang="EN-US">mapping</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span>
		</p>
<img src ="http://www.blogjava.net/RR00/aggbug/64886.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-21 21:08 <a href="http://www.blogjava.net/RR00/articles/64886.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.sql.SQLException: Connection is broken</title><link>http://www.blogjava.net/RR00/articles/63243.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Sat, 12 Aug 2006 12:11:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/63243.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/63243.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/63243.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/63243.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/63243.html</trackback:ping><description><![CDATA[
		<p>
				<font style="BACKGROUND-COLOR: #ffc0cb">WARN - SettingsFactory.buildSettings(103) | Could not obtain connection metadata</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffc0cb">java.sql.SQLException: Connection is broken<br />        at org.hsqldb.jdbc.jdbcUtil.sqlException(Unknown Source)<br />        at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)<br />        at org.hsqldb.jdbc.jdbcStatement.executeQuery(Unknown Source)<br />        at org.hsqldb.jdbc.jdbcDatabaseMetaData.execute(Unknown Source)<br />        at org.hsqldb.jdbc.jdbcDatabaseMetaData.getDatabaseProductName(Unknown S<br />ource)<br />        at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:<br />75)<br />        at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:1881<br />)<br />        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.jav<br />a:1174)<br />        at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSession<br />Factory(LocalSessionFactoryBean.java:825)<br /><br /><br /></font>
				<font style="BACKGROUND-COLOR: #ffff00">因为我在lib中放了hsqldb-1.7.3.0.jar所以导致了错误！<br /></font>
		</p>
<img src ="http://www.blogjava.net/RR00/aggbug/63243.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-08-12 20:11 <a href="http://www.blogjava.net/RR00/articles/63243.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts Recipes: Hibernate and Struts</title><link>http://www.blogjava.net/RR00/articles/13308.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Sun, 18 Sep 2005 06:11:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/13308.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/13308.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/13308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/13308.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/13308.html</trackback:ping><description><![CDATA[&nbsp;
<P>
<H1 align=center>Struts Recipes: Hibernate and Struts</H1>
<H3 align=center>Add the power of Hibernate to your Struts application</H3>
<P></P><!--<BLOCKQUOTE><STRONG>Summary</STRONG><BR>-->
<BLOCKQUOTE><STRONG>Summary</STRONG><BR>In this excerpt from <EM>Struts Recipes,</EM> (Manning Publications, December 2004) authors George Franciscus and Danilo Gurovich illustrate how to use Hibernate in a Struts application. They also show how to create a Struts plug-in to improve performance. (<EM>2,200 words;</EM> <STRONG>January 24, 2005</STRONG>) </BLOCKQUOTE><!--</BLOCKQUOTE>--><A href="http://www.javaworld.com/feedback" target=Feedback><STRONG>By George Franciscus and Danilo Gurovich </STRONG></A><BR><BR>
<P><IMG height=29 alt=P src="http://www.javaworld.com/javaworld/abcs/P.gif" width=24 align=left>ersistence is a fundamental piece of an application. Obviously, without persistence all work would be lost. However, persistence means different things to different people. The length of time something must be persisted is a fundamental qualifier in choosing a persistence storage medium. For example, the HTTP session may be suitable when the life of a piece of data is limited to the user's session. In contrast, persistence over several sessions, or several users, requires a database. The volume of data is another important qualifier. For example, best practices suggest large amounts of data should not be stored in an HTTP session. In those circumstances, you need to consider a database. In this recipe we target persistence in a database. 
<P>The type of database you choose has an important influence on your architecture and design. As object-oriented developers, we tend to represent data as an interconnected web of objects as a means to describe the business problem at hand—this is often called a domain model. However, the most common storage medium is based on a relational paradigm. Unless our object model mirrors a relational structure, the in-memory representation of our data is at odds with the means to persist it. This problem is called the <EM>mismatch paradigm</EM>. One of the most popular tools to address the mismatch problem is a category of tools called object-relational mappers. An object-relational mapper is software used to transform an object view of the data into a relational one, and provide persistence services, such as create, read, update, and delete (CRUD). Many good papers have been written on object-relational mappers, but in essence, they all speak to the Data Mapper pattern. One of the most popular object-relational mappers is the open source Hibernate project. 
<P>In this recipe, we show you how to employ Hibernate in a Struts application. In addition, we will show you how to create a Struts plug-in to give your Hibernate-powered Struts applications a performance boost. 
<P><FONT size=+1><STRONG>Recipe</STRONG></FONT><BR>In this recipe, we use an example to illustrate everything you need to do to use Hibernate in a Struts application. We create an application to retrieve and display elements from the chemical periodic table. The application offers the user a search page to look for an element by element symbol. The application responds by searching the database for an element matching the symbol name and returns information about the element. 
<P>We'll start by showing you how to get the Hypersonic database server up and running. With the database server started, we create the table and data required to exercise the application. Once the database is ready to go, we'll create all the Hibernate artifacts required to execute this application by using the Hypersonic database server. The next step is to respond to search requests by calling upon Hibernate to handle database access from inside our <CODE>Action</CODE>. Because creating Hibernate factory objects is expensive, we'll create a Struts plug-in to create the factory and store it in context. 
<P>Let's start by bringing up the Hypersonic database server. You need to download Hypersonic from http://hsqldb.sourceforge.net/. Place <CODE>hsqldb.jar</CODE> in your classpath and launch Hypersonic by entering the following command in your DOS prompt: 
<P><CODE>
<P><CODE>java org.hsqldb.Server </CODE>
<P></CODE>
<P>Although the server's response varies from one version of Hypersonic to another, the following response is a typical indication that Hypersonic is ready to serve database requests. 
<P><CODE>
<P><CODE>Server 1.6 is running<BR>Press [Ctrl]+{c} to abort </CODE>
<P></CODE>
<P>With the database server up and running, we are ready to create the elements table and populate it with data, as shown in Listing 1. 
<P><STRONG>Listing 1. Create and populate elements tables</STRONG> 
<P><CODE>
<P><CODE>create table elements (id integer(3) IDENTITY,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name char(30),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; number char(30),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mass char(30),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; symbol char(2));<BR><BR>CREATE UNIQUE INDEX ui_elements_pk ON elements (symbol)<BR><BR>insert into elements ( name, number, mass, symbol) values ('Manganese','25','55','Mn');<BR>insert into elements ( name, number, mass, symbol) values ('Zinc','30','65','Zn');<BR>insert into elements ( name, number, mass, symbol) values ('Thulium','69','169','Tm');<BR>insert into elements ( name, number, mass, symbol) values ('Californium','98','251','Cf');<BR>insert into elements ( name, number, mass, symbol) values ('Gold','79','197','Au');<BR>insert into elements ( name, number, mass, symbol) values ('Ytterbium','70','173','Yb');<BR>insert into elements ( name, number, mass, symbol) values ('Molybdenum','42','96','Mo');<BR>insert into elements ( name, number, mass, symbol) values ('Palladium','46','106','Pd'); </CODE>
<P></CODE>
<P>Listing 1 presents the SQL commands necessary to create the elements table, create a unique index on <CODE>symbol</CODE>, and insert data We have only presented a few of the periodic elements. We'll leave it to you to dust off your high school chemistry textbook to create data for the remaining elements. 
<P>Listing 2 presents the <CODE>Element</CODE> JavaBean used to store data retrieved from the database. 
<P><STRONG>Listing 2. Element JavaBean</STRONG> 
<P><CODE>
<P><CODE>package com.strutsrecipes.hibernate.beans;<BR><BR>public class Element {<BR>&nbsp;&nbsp; private String name;<BR>&nbsp;&nbsp; private String symbol;<BR>&nbsp;&nbsp; private String number;<BR>&nbsp;&nbsp; private String mass;<BR>&nbsp;&nbsp; private int id;<BR><BR>&nbsp;&nbsp; public Element() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super();<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public Element(String name, String symbol, String number, String mass) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.symbol = symbol;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.number = number;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mass = mass;<BR><BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public int getId() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return id;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void setId(int id) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.id = id;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public String getMass() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return mass;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public String getName() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return name;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public String getNumber() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return number;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public String getSymbol() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return symbol;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void setMass(String mass) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.mass = mass;<BR><BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void setName(String name) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void setNumber(String number) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.number = number;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void setSymbol(String symbol) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.symbol = symbol;<BR>&nbsp;&nbsp; }<BR>} </CODE>
<P></CODE>
<P>Hibernate is an object-relational mapping tool. Its job is to map objects to relational tables and vice versa. Therefore, we must tell Hibernate how to map the columns in the "elements" table to the properties of the <CODE>Elements</CODE> JavaBean. This is done using the <CODE>Element.hbm.xml</CODE> file. The information embodied in this file is required to empower Hibernate to copy data from the table to the <CODE>Elements</CODE> JavaBean. If we were using Hibernate to update data, the information in the <CODE>Element.hbm.xml</CODE> file would be used to extract data from the <CODE>Elements</CODE> JavaBean to generate SQL update statements. Listing 3 presents <CODE>Element.hbm.xml</CODE>. 
<P><STRONG>Listing 3. Element.hbm.xml</STRONG> 
<P><CODE>
<P><CODE>&lt;?xml version="1.0"?&gt;<BR>&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"<BR>&nbsp;&nbsp; "http://hibernate.sf.net/hibernate-mapping-2.0.dtd"&gt;<BR><BR>&lt;hibernate-mapping&gt;<BR>&nbsp;&nbsp; &lt;class name="com.strutsrecipes.hibernate.beans.Element" table="elements"&gt;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;id name="id" column="id"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator class="native"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/id&gt;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="name" column="name"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="number" column="number"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="mass" column="mass"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="symbol" column="symbol"/&gt;<BR>&nbsp;&nbsp; &lt;/class&gt;<BR>&lt;/hibernate-mapping&gt; </CODE>
<P></CODE>
<P>Let's step through Listing 3 
<P>We declare the full package name of the class to be associated with the "elements" table. We then declare the name of the table associated with that class. Next, we declare the mapping from the <CODE>id</CODE> JavaBean property to the <CODE>id</CODE> column. Because the property and column names have the same value, we could have omitted the column attribute, but we have explicitly declared the column for clarity purposes. The <CODE>&lt;id&gt;</CODE> tag is a special tag. It is used to declare the primary key for the table. The enclosing <CODE>&lt;generator&gt;</CODE> tag instructs Hibernate to generate the key in whichever way is most appropriate for the database implementation. You should consult Hibernate documentation for more information on the <CODE>&lt;id&gt;</CODE> tag. Finally, we declare mapping for the remaining JavaBean properties. Once again the <CODE>column</CODE> attribute is declared for clarification purposes. 
<P>Once the mapping file has been broken down in detail, it's all rather straightforward. It simply describes which table maps to which class and which JavaBean properties map to which column names. Later on we will tell you where to place this file. 
<P>Next, we configure Hibernate by declaring environmental information. In Listing 4, we present the <CODE>hibernate.cfg.xml</CODE> file. 
<P><STRONG>Listing 4. hibernate.cfg.xml</STRONG> 
<P><CODE>
<P><CODE>&lt;?xml version='1.0' encoding='utf-8'?&gt;<BR>&lt;!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"<BR>&nbsp;&nbsp; "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"&gt;<BR><BR>&lt;hibernate-configuration&gt;<BR>&nbsp;&nbsp; &lt;session-factory&gt;<BR>&nbsp;&nbsp; &lt;property name="dialect"&gt;net.sf.hibernate.dialect.HSQLDialect&lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name="connection.driver_class"&gt;org.hsqldb.jdbcDriver&lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name="connection.username"&gt;sa&lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name="connection.password"&gt;&lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name="connection.url"&gt;jdbc:hsqldb:hsql://127.0.0.1&lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name="show_sql"&gt; &lt;/property&gt;<BR>&nbsp;&nbsp; &lt;property name=""&gt;true&lt;/property&gt;<BR><BR>&nbsp;&nbsp; &lt;mapping resource="/com/strutscookbook/hibernate/beans/Element.hbm.xml"/&gt;<BR>&lt;/session-factory&gt;<BR>&lt;/hibernate-configuration&gt; </CODE>
<P></CODE>
<P>Let's step through Listing 4. 
<P>We start by specifying the database implementation dialect that allows Hibernate to take advantage of implementation-specific features. We declare the Hypersonic dialect. You should consult the Hibernate documentation to choose the appropriate dialect for your database. We then declare the database driver. You must ensure this driver is in your application's classpath. We then declare the database username, the database password, and the database connection URL. Next, we instruct Hibernate to display the SQL generated at runtime in the log. 
<P>The <CODE>hibernate.cfg.xml</CODE> file must be placed in your classpath. 
<P>The procedure to use Hibernate within your application requires the following steps: 
<P>
<OL>
<LI>Create a Hibernate configuration object 
<P></P>
<LI>Use the Hibernate configuration object to create a Hibernate factory object 
<P></P>
<LI>Use the Hibernate factory object to create a Hibernate session object 
<P></P>
<LI>Use the Hibernate session object to start a transaction (optional) 
<P></P>
<LI>Employ the Hibernate session object to create, read, update, and delete data on the database 
<P></P>
<LI>Commit the transaction (optional) 
<P></P>
<LI>Close the session</LI></OL>
<P>A Hibernate best practice is to create and cache the Hibernate factory to enhance performance. Therefore, we will create a Struts plug-in to perform Steps 1 and 2 and cache the Hibernate factory in the servlet context, as shown in Listing 5. 
<P><STRONG>Listing 5. HibernatePlugin.java</STRONG> 
<P><CODE>
<P><CODE>package com.strutsrecipes.hibernate.plugin;<BR><BR>import java.net.URL;<BR>import javax.servlet.ServletException;<BR><BR>import net.sf.hibernate.HibernateException;<BR>import net.sf.hibernate.MappingException;<BR>import net.sf.hibernate.SessionFactory;<BR>import net.sf.hibernate.cfg.Configuration;<BR><BR>import org.apache.commons.logging.Log;<BR>import org.apache.commons.logging.LogFactory;<BR>import org.apache.struts.action.ActionServlet;<BR>import org.apache.struts.action.PlugIn;<BR>import org.apache.struts.config.ModuleConfig;<BR><BR>public class HibernatePlugin implements PlugIn {<BR>&nbsp;&nbsp; private Configuration config;<BR>&nbsp;&nbsp; private SessionFactory factory;<BR>&nbsp;&nbsp; private String path = "/hibernate.cfg.xml";<BR>&nbsp;&nbsp; private static Class clazz = HibernatePlugin.class;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static final String KEY_NAME = clazz.getName();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private static Log log = LogFactory.getLog(clazz);<BR><BR>&nbsp;&nbsp; public void setPath(String path) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.path = path;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void init(ActionServlet servlet, ModuleConfig modConfig)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws ServletException {<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL url = HibernatePlugin.class.getResource(path);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; config = new Configuration().configure(url);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; factory = config.buildSessionFactory();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; servlet.getServletContext().setAttribute(KEY_NAME, factory);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (MappingException e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("mapping error", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new ServletException();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (HibernateException e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("hibernate error", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new ServletException();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void destroy() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; factory.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (HibernateException e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("unable to close factory", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp; }<BR>}</CODE> 
<P></CODE>
<P>Creating a Struts plug-in requires only two steps. First, create a class implementing <CODE>org.apache.struts.action.PlugIn</CODE> (Listing 5). Second, define a <CODE>&lt;plug-in&gt;</CODE> tag in the <CODE>struts-config.xml</CODE> file (Listing 6). 
<P>Let's step through Listing 5. 
<P>We create a constant to hold the name of the servlet context attribute key. We have chosen to use the <CODE>HibernatePlugin</CODE> class name. Notice the constant is static public final. We use the <CODE>HibernatePlugin</CODE> class to access the key name in the <CODE>Action</CODE> (Listing 7). We define the path property. By default, the <CODE>Hibernate-Plugin</CODE> looks for the Hibernate configuration file at <CODE>/hibernate.cfg.xml</CODE>. You can use this property to load the Hibernate configuration file from another filename and directory anywhere on the classpath. Next, we use the classloader to find the Hibernate configuration file and then we create the Hibernate configuration object. We use the Hibernate configuration object to create a Hibernate factory object and then we store the Hibernate factory object in the servlet context. The factory is now available to any code with a reference to the servlet. 
<P>As a good practice, we close the factory in the destroy method. 
<P>Listing 6 presents the application struts-config. The only thing out of the ordinary here is the <CODE>&lt;plug-in&gt;</CODE> tag. This is where we declare the Hibernate plug-in, which creates and caches the Hibernate factory object. 
<P><STRONG>Listing 6. struts-config.xml</STRONG> 
<P><CODE>
<P><CODE>&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;<BR><BR>&lt;!DOCTYPE struts-config PUBLIC<BR>&nbsp;&nbsp; "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"<BR>&nbsp;&nbsp; "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;<BR><BR>&lt;struts-config&gt;<BR>&nbsp;&nbsp; &lt;form-beans&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;form-bean name="searchForm"type="com.strutsrecipes.hibernate.forms.SearchForm"/&gt;<BR>&nbsp;&nbsp; &lt;/form-beans&gt;<BR><BR>&nbsp;&nbsp; &lt;global-forwards&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward name="search" path="/search.jsp"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward name="searchsubmit" path="/searchsubmit.do"/&gt;<BR>&nbsp;&nbsp; &lt;/global-forwards&gt;<BR><BR>&nbsp;&nbsp; &lt;action-mappings&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;action path="/searchsubmit"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="com.strutsrecipes.hibernate.actions.SearchAction"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name="searchForm"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scope="request"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;input="/search.jsp"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward name="success" path="/element.jsp"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/action&gt;<BR>&nbsp;&nbsp; &lt;/action-mappings&gt;<BR><BR>&nbsp;&nbsp; &lt;plug-in className="com.strutsrecipes.hibernate.plugin.HibernatePlugin"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property property="path" value="/hibernate.cfg.xml"/&gt;<BR>&nbsp;&nbsp; &lt;/plug-in&gt;<BR>&lt;/struts-config&gt; </CODE>
<P></CODE>
<P>Listing 7 presents the <CODE>SearchForm</CODE> used to search for an element. It's very simple because the user can only search by element symbol. 
<P><STRONG>Listing 7. SearchForm.java</STRONG> 
<P><CODE>
<P><CODE>package com.strutsrecipes.hibernate.forms;<BR><BR>import org.apache.struts.action.ActionForm;<BR>public class SearchForm extends ActionForm {<BR>&nbsp;&nbsp; String symbol;<BR><BR>&nbsp;&nbsp; public String getSymbol() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return symbol;<BR>&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp; public void setSymbol(String symbol) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.symbol = symbol;<BR>&nbsp;&nbsp; }<BR>} </CODE>
<P></CODE>
<P>Let's have a look at the <CODE>SearchAction</CODE> in Listing 8. Although you may decide to employ Hibernate in other areas of your application architecture, we have chosen to use it in the <CODE>Action</CODE>. We'll defer the discussion of the other alternatives to the discussion section. 
<P><STRONG>Listing 8. SearchAction.java</STRONG> 
<P><CODE>
<P><CODE>package com.strutsrecipes.hibernate.actions;<BR><BR>import java.util.List;<BR><BR>import javax.servlet.http.HttpServletRequest;<BR>import javax.servlet.http.HttpServletResponse;<BR><BR>import org.apache.commons.logging.Log;<BR>import org.apache.commons.logging.LogFactory;<BR><BR>import net.sf.hibernate.Hibernate;<BR>import net.sf.hibernate.HibernateException;<BR>import net.sf.hibernate.Session;<BR>import net.sf.hibernate.SessionFactory;<BR><BR>import org.apache.struts.action.Action;<BR>import org.apache.struts.action.ActionError;<BR>import org.apache.struts.action.ActionErrors;<BR>import org.apache.struts.action.ActionForm;<BR>import org.apache.struts.action.ActionForward;<BR>import org.apache.struts.action.ActionMapping;<BR><BR>import com.strutsrecipes.hibernate.beans.Element;<BR>import com.strutsrecipes.hibernate.forms.SearchForm;<BR>import com.strutsrecipes.hibernate.plugin.HibernatePlugin;<BR><BR>public class SearchAction extends Action {<BR>&nbsp;&nbsp; private static Log log = LogFactory.getLog(SearchAction.class);<BR><BR>&nbsp;&nbsp; final public static String HQL_FIND_ELEMENT =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"from com.strutsrecipes.hibernate.beans.Element as e where e.symbol = ?";<BR><BR>&nbsp;&nbsp; public ActionForward execute(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionMapping mapping,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionForm form,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest request,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse response)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws Exception {<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SearchForm searchForm = (SearchForm) form;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element element = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List elements = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SessionFactory factory = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Session session = null;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; factory =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(SessionFactory) servlet.getServletContext()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getAttribute(HibernatePlugin.KEY_NAME);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session = factory.openSession();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elements =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.find(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HQL_FIND_ELEMENT,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchForm.getSymbol(),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hibernate.STRING);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!elements.isEmpty()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;element = (Element) elements.get(0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (HibernateException e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("Hibernate error", e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error("Hibernate exception encountered");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (element != null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.setAttribute("element", element);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return mapping.findForward("success");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionErrors errors = new ActionErrors();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errors.add(ActionErrors.GLOBAL_ERROR,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ActionError("error.notfound"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;saveErrors(request, errors);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return mapping.getInputForward();<BR>&nbsp;&nbsp; }<BR>} </CODE>
<P></CODE>
<P>Let's take a quick overview of what happens in the <CODE>SearchAction</CODE>. The <CODE>SearchAction</CODE> uses the <CODE>SearchForm.getSymbol()</CODE> method to obtain the element symbol entered by the user on the search page. Hibernate is used to search the database and convert the data stored in the database to an <CODE>Element</CODE> object. The <CODE>Element</CODE> object is placed in request context for the JavaServer Pages (JSP) page. Let's step through Listing 8 line by line to see how it's done in detail. 
<P>First, we declare a constant to search the database. We next cast the form to <CODE>SearchForm</CODE> and then we obtain the Hibernate factory. Recall the Hibernate plug-in has already created the factory and cached it in the servlet context. Next, we obtain a session. The session obtains a connection to the database. Hibernate uses the configuration information we created in Listing 4 to connect to the database. We then search the database. 
<P>There are other ways to employ Hibernate to search the database, but the <CODE>find</CODE> method is appropriate whenever a search doesn't use the primary key. Notice, we have the <CODE>HQL_FIND_ELEMENT</CODE> constant declared. The SQL defined in <CODE>HQL_FIND_ELEMENT</CODE> looks somewhat like standard SQL, but not quite. The SQL used by Hibernate is proprietary to Hibernate and reflects an object-oriented version of SQL, rather than the relational SQL to which you are accustomed. 
<P>Let's delve into the Hibernate SQL (HQL) code snippet. 
<P><CODE>
<P><CODE>from com.strutsrecipes.hibernate.beans.Element as e where e.symbol = ?</CODE> 
<P></CODE>
<P>This statement tells Hibernate to select all <CODE>Element</CODE> objects residing in the <CODE>com.strutsrecipes.hibernate.beans</CODE> package. The <CODE>where</CODE> clause filters the list to only those elements whose symbols match a runtime parameter. The <CODE>as e</CODE> indicates that <CODE>e</CODE> may be used as an alias elsewhere in the HQL, as we have done in the <CODE>where</CODE> clause. You can see that we are selecting objects, not rows, in the database. Hibernate uses the information in Listing 4 to map the class we are interested in to its associated table. In this example, the relationship between the table and the object are very close, but that does not necessarily need to be the case. 
<P>The second and third arguments to the <CODE>find</CODE> method are the value and data type of the HQL replacement parameter. The Hibernate reference material describes other ways to replace runtime parameters. 
<P>The <CODE>find</CODE> method always returns a <CODE>List</CODE>. In this case, we obtain a list of <CODE>Element</CODE> objects. We are confident that a maximum of one instance is returned because the "elements" table has a unique key constraint on the <CODE>symbol</CODE> column (see Listing 1). 
<P>Returning to Listing 8, we copy the element reference in the first position in the list to the element variable. To deal with any Hibernate exceptions, we have chosen to log the exception and present the user a "not found" message, but you may decide to present a different message or use declarative exception handling. Next, we close the session. Closing the session in the <CODE>finally</CODE> clause guarantees it is attempted even when exceptions are thrown. We store the <CODE>Element</CODE> object in the request context and finally we build the <CODE>ActionError</CODE> when the symbol can't be found. For the sake of completeness, we have presented the <CODE>search.jsp</CODE> (Listing 9) and the <CODE>element.jsp</CODE> (Listing 10). 
<P><STRONG>Listing 9. Search.jsp</STRONG> 
<P><CODE>
<P><CODE>&lt;%@ page language="java" %&gt;<BR>&lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %&gt;<BR><BR>&lt;html:html&gt;<BR>&lt;body&gt;<BR>&nbsp;&nbsp; &lt;h1&gt;Search for an Element&lt;/h1&gt;<BR><BR>&nbsp;&nbsp; &lt;html:form action="/searchsubmit.do"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;symbol &lt;form:text property="symbol"/&gt;<BR>&nbsp;&nbsp; &lt;html:submit value="Search"/&gt;<BR>&nbsp;&nbsp; &lt;/html:form&gt;<BR><BR>&nbsp;&nbsp; &lt;html:errors/&gt;<BR><BR>&lt;/body&gt;<BR>&lt;/html:html&gt; </CODE>
<P></CODE>
<P><STRONG>Listing 10. Element.jsp</STRONG> 
<P><CODE>
<P><CODE>&lt;%@ page language="java" %&gt;<BR>&lt;%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %&gt;<BR>&lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %&gt;<BR><BR>&lt;html:html&gt;<BR>&nbsp;&nbsp; &lt;h1&gt;Periodic Element&lt;/h1&gt;<BR>&nbsp;&nbsp; Name: &lt;bean:write name="element" property="name"/&gt;&lt;br&gt;<BR>&nbsp;&nbsp; Symbol: &lt;bean:write name="element" property="symbol"/&gt;&lt;br&gt;<BR>&nbsp;&nbsp; Number: &lt;bean:write name="element" property="number"/&gt;&lt;br&gt;<BR>&nbsp;&nbsp; Mass: &lt;bean:write name="element" property="mass"/&gt;&lt;br&gt;<BR><BR>&nbsp;&nbsp; &lt;html:link forward="search"&gt;Search&lt;/html:link&gt;&lt;p&gt;<BR>&lt;/html:html&gt; </CODE>
<P></CODE>
<P>Before putting Hibernate to work, consult the Hibernate documentation to ensure you have all the required Hibernate jar files in your classpath. 
<P><FONT size=+1><STRONG>Discussion</STRONG></FONT><BR>Persistence of data is a tedious and laborious job. To make matters worse, a considerable effort must be spent transforming an object-oriented representation of the data to a relational one, and vice versa. Fortunately, several good object-relational mappers exist to ease this burden. In this recipe, we explored Hibernate—one of the most popular open source object-relational mappers available to Java programmers. 
<P>Hibernate is a very rich product with many unexplored features left for you to discover. Our simple example is limited to <CODE>read</CODE> behavior, but the rest of the CRUD family is just as easy. Update functionality is as simple as accessing the desired element, calling the desired JavaBean setter, and calling the session commit method. Hibernate takes care of generating the SQL and updating the table. A <CODE>delete</CODE> is also rather simple—<CODE>session.delete(element)</CODE> is all it takes! Finally, <CODE>create</CODE> only requires instantiating the object, calling the setters, and calling <CODE>session.save(element)</CODE>. 
<P>Hibernate best practices recommend caching the Hibernate factory object. We chose to create and cache the factory using a Struts plug-in. Alternatively, you could have chosen to cache using any other means in your arsenal. 
<P>Although this recipe can serve you well, there are some drawbacks. First, we have exposed Hibernate to the Struts <CODE>Action</CODE>. Migrating to another persistence layer framework requires us to change every <CODE>Action</CODE> employing Hibernate. Second, our persistence is tightly coupled to the presentation layer. This coupling denies us the opportunity to reuse the persistence logic in some other presentation mechanism, such as a batch program. 
<P>Although there is room for improvement, this recipe is suitable when you do not expect to reuse your persistence logic. You may find yourself in this situation developing prototypes or small throwaway applications. <BR><BR></P>
<P><STRONG>About the author</STRONG><BR>George Franciscus is a J2EE consultant and Struts authority. He is a coauthor of Manning's <EM>Struts in Action</EM>. 
<P>Danilo Gurovich is a manager of Web engineering at an e-commerce company. He has designed e-commerce and ERP/EAI Struts applications, and has led teams who have built them. <BR></P><img src ="http://www.blogjava.net/RR00/aggbug/13308.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-09-18 14:11 <a href="http://www.blogjava.net/RR00/articles/13308.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第 4 章  配置 </title><link>http://www.blogjava.net/RR00/articles/9559.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Mon, 08 Aug 2005 04:55:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/9559.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/9559.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/9559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/9559.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/9559.html</trackback:ping><description><![CDATA[<DIV class=chapter lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title><A name=session-configuration></A>&nbsp;</H2></DIV></DIV>
<DIV></DIV></DIV>
<P>由于Hibernate是为了能在各种不同环境下工作而设计的, 因此存在着大量的配置参数. 幸运的是多数配置参数都 有比较直观的默认值, 并有随Hibernate一同分发的配置样例<TT class=literal>hibernate.properties</TT> (位于<TT class=literal>etc/</TT>)来展示各种配置选项. 所需做的仅仅是将这个样例文件复制到类路径 (classpath)下做一些自定义的修改. </P>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-programmatic></A>4.1.&nbsp; 可编程的配置方式 </H2></DIV></DIV>
<DIV></DIV></DIV>
<P>一个<TT class=literal>org.hibernate.cfg.Configuration</TT>实例代表了一个应用程序中Java类型 到SQL数据库映射的完整集合. <TT class=literal>Configuration</TT>被用来构建一个(不可变的 (immutable))<TT class=literal>SessionFactory</TT>. 映射定义则由不同的XML映射定义文件编译而来. </P>
<P>你可以直接实例化<TT class=literal>Configuration</TT>来获取一个实例，并为它指定XML映射定义 文件. 如果映射定 义文件在类路径(classpath)中, 请使用<TT class=literal>addResource()</TT>: </P><PRE class=programlisting>Configuration cfg = new Configuration()
    .addResource("Item.hbm.xml")
    .addResource("Bid.hbm.xml");</PRE>
<P>一个替代方法（有时是更好的选择）是，指定被映射的类，让Hibernate帮你寻找映射定义文件: </P><PRE class=programlisting>Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class);</PRE>
<P>Hibernate将会在类路径(classpath)中寻找名字为 <TT class=literal>/org/hibernate/auction/Item.hbm.xml</TT>和 <TT class=literal>/org/hibernate/auction/Bid.hbm.xml</TT>映射定义文件. 这种方式消除了任何对文件名的硬编码(hardcoded). </P>
<P><TT class=literal>Configuration</TT>也允许你指定配置属性: </P><PRE class=programlisting>Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class)
    .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
    .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
    .setProperty("hibernate.order_updates", "true");</PRE>
<P>当然这不是唯一的传递Hibernate配置属性的方式, 其他可选方式还包括: </P>
<DIV class=orderedlist>
<OL type=1 compact>
<LI>
<P>传一个<TT class=literal>java.util.Properties</TT>实例给 <TT class=literal>Configuration.setProperties()</TT>. </P>
<LI>
<P>将<TT class=literal>hibernate.properties</TT>放置在类路径(classpath)的根目录下 (root directory). </P>
<LI>
<P>通过<TT class=literal>java -Dproperty=value</TT>来设置系统 (<TT class=literal>System</TT>)属性. </P>
<LI>
<P>在<TT class=literal>hibernate.cfg.xml</TT>中加入元素 <TT class=literal>&lt;property&gt;</TT> (稍后讨论). </P></LI></OL></DIV>
<P>如果想尽快体验Hbernate, <TT class=literal>hibernate.properties</TT>是最简单的方式. </P>
<P><TT class=literal>Configuration</TT>实例是一个启动期间（startup-time）的对象, 一旦<TT class=literal>SessionFactory</TT>创建完成它就被丢弃了. </P></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-sessionfactory></A>4.2.&nbsp; 获得SessionFactory </H2></DIV></DIV>
<DIV></DIV></DIV>
<P>当所有映射定义被<TT class=literal>Configuration</TT>解析后, 应用程序必须获得一个用于构造<TT class=literal>Session</TT>实例的工厂. 这个工厂将被应用程序的所有线程共享: </P><PRE class=programlisting>SessionFactory sessions = cfg.buildSessionFactory();</PRE>
<P>Hibernate允许你的应用程序创建多个<TT class=literal>SessionFactory</TT>实例. 这对 使用多个数据库的应用来说很有用. </P></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-hibernatejdbc></A>4.3.&nbsp; JDBC连接 </H2></DIV></DIV>
<DIV></DIV></DIV>
<P>通常你希望<TT class=literal>SessionFactory</TT>来为你创建和缓存(pool)JDBC连接. 如果你采用这种方式, 只需要如下例所示那样，打开一个<TT class=literal>Session</TT>: </P><PRE class=programlisting>Session session = sessions.openSession(); // open a new Session</PRE>
<P>一旦你需要进行数据访问时, 就会从连接池(connection pool)获得一个JDBC连接. </P>
<P>为了使这种方式工作起来, 我们需要向Hibernate传递一些JDBC连接的属性. 所有Hibernate属性的名字和语义都在<TT class=literal>org.hibernate.cfg.Environment</TT>中定义. 我们现在将描述JDBC连接配置中最重要的设置. </P>
<P>如果你设置如下属性，Hibernate将使用<TT class=literal>java.sql.DriverManager</TT>来获得(和缓存)JDBC连接 : </P>
<DIV class=table><A name=d0e2044></A>
<P class=title><B>表&nbsp;4.1.&nbsp; Hibernate JDBC属性 </B></P>
<TABLE summary="&#10;                Hibernate JDBC属性&#10;            " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>属性名 </TH>
<TH>用途 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>hibernate.connection.driver_class</TT></TD>
<TD><SPAN class=emphasis><EM>jdbc驱动类</EM></SPAN></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.url</TT></TD>
<TD><SPAN class=emphasis><EM>jdbc URL</EM></SPAN></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.username</TT></TD>
<TD><SPAN class=emphasis><EM>数据库用户</EM></SPAN></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.password</TT></TD>
<TD><SPAN class=emphasis><EM>数据库用户密码</EM></SPAN></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.pool_size</TT></TD>
<TD><SPAN class=emphasis><EM>连接池容量上限数目</EM></SPAN></TD></TR></TBODY></TABLE></DIV>
<P>但Hibernate自带的连接池算法相当不成熟. 它只是为了让你快些上手<SPAN class=emphasis><EM>，不适合用于产品系统</EM></SPAN>或性能测试中。 出于最佳性能和稳定性考虑你应该使用第三方的连接池。只需要连接池的特定设置替换 <TT class=literal>hibernate.connection.pool_size</TT>。这将关闭Hibernate自带的连接池. 例如, 你可能会想用C3P0. </P>
<P>C3P0是一个随Hibernate一同分发的开源的JDBC连接池, 它位于<TT class=literal>lib</TT>目录下。 如果你设置了<TT class=literal>hibernate.c3p0.*</TT>相关的属性, Hibernate将使用 <TT class=literal>C3P0ConnectionProvider</TT>来缓存JDBC连接. 如果你更原意使用Proxool, 请参考发 行包中的<TT class=literal>hibernate.properties</TT>并到Hibernate网站获取更多的信息. </P>
<P>这是一个使用C3P0的<TT class=literal>hibernate.properties</TT>样例文件: </P><A name=c3p0-configuration></A><PRE class=programlisting>hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect</PRE>
<P>为了能在应用程序服务器(application server)中使用Hibernate, 你应当总是将Hibernate 配置成注册在JNDI中的<TT class=literal>Datasource</TT>处获得连接，你至少需要设置下列属性中的一个: </P>
<DIV class=table><A name=d0e2126></A>
<P class=title><B>表&nbsp;4.2.&nbsp; Hibernate数据源属性 </B></P>
<TABLE summary="&#10;                Hibernate数据源属性&#10;            " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>属性名 </TH>
<TH>用途 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>hibernate.connection.datasource</TT></TD>
<TD><SPAN class=emphasis><EM>数据源JNDI名字</EM></SPAN></TD></TR>
<TR>
<TD><TT class=literal>hibernate.jndi.url</TT></TD>
<TD><SPAN class=emphasis><EM>JNDI提供者的URL</EM></SPAN> (可选) </TD></TR>
<TR>
<TD><TT class=literal>hibernate.jndi.class</TT></TD>
<TD><SPAN class=emphasis><EM>JNDI <TT class=literal>InitialContextFactory</TT>类</EM></SPAN> (可选) </TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.username</TT></TD>
<TD><SPAN class=emphasis><EM>数据库用户</EM></SPAN> (可选) </TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.password</TT></TD>
<TD><SPAN class=emphasis><EM>数据库用户密码</EM></SPAN> (可选) </TD></TR></TBODY></TABLE></DIV>
<P>这里有一个使用应用程序服务器JNDI数据源的<TT class=literal>hibernate.properties</TT>样例文件: </P><PRE class=programlisting>hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect</PRE>
<P>从JNDI数据源获得的JDBC连接将自动参与应用程序服务器中容器管理的事务(container-managed transactions)中去. </P>
<P>任何连接(connection)配置属性的属性名要以"<TT class=literal>hibernate.connnection</TT>"前缀开头. 例如, 你可能会使用<TT class=literal>hibernate.connection.charSet</TT>来指定<TT class=literal>charSet</TT>. </P>
<P>通过实现<TT class=literal>org.hibernate.connection.ConnectionProvider</TT>接口，你可以定义属于 你自己的获得JDBC连接的插件策略。通过设置<TT class=literal>hibernate.connection.provider_class</TT>， 你可以选择一个自定义的实现. </P></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-optional></A>4.4.&nbsp; 可选的配置属性 </H2></DIV></DIV>
<DIV></DIV></DIV>
<P>有大量属性能用来控制Hibernate在运行期的行为. 它们都是可选的, 并拥有适当的默认值. </P>
<P><SPAN class=emphasis><EM>警告: 其中一些属性是"系统级(system-level)的".</EM></SPAN> 系统级属性可以通过<TT class=literal>java -Dproperty=value</TT>或 <TT class=literal>hibernate.properties</TT>来设置, 而<SPAN class=emphasis><EM>不能</EM></SPAN>用上面描述的其他方法来设置. </P>
<DIV class=table><A name=configuration-optional-properties></A>
<P class=title><B>表&nbsp;4.3.&nbsp; Hibernate配置属性 </B></P>
<TABLE summary="&#10;                Hibernate配置属性&#10;            " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>属性名 </TH>
<TH>用途 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>hibernate.dialect</TT></TD>
<TD>一个Hibernate <TT class=literal>Dialect</TT>类名允许Hibernate针对特定的关系数据库生成优化的SQL. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>full.classname.of.Dialect</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.show_sql</TT></TD>
<TD>输出所有SQL语句到控制台. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.default_schema</TT></TD>
<TD>在生成的SQL中, 将给定的schema/tablespace附加于非全限定名的表名上. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>SCHEMA_NAME</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.default_catalog</TT></TD>
<TD>在生成的SQL中, 将给定的catalog附加于没全限定名的表名上. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>CATALOG_NAME</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.session_factory_name</TT></TD>
<TD><TT class=literal>SessionFactory</TT>创建后，将自动使用这个名字绑定到JNDI中. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>jndi/composite/name</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.max_fetch_depth</TT></TD>
<TD>为单向关联(一对一, 多对一)的外连接抓取（outer join fetch）树设置最大深度. 值为<TT class=literal>0</TT>意味着将关闭默认的外连接抓取. 
<P><SPAN class=strong>取值</SPAN> 建议在<TT class=literal>0</TT>到<TT class=literal>3</TT>之间取值 </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.default_batch_fetch_size</TT></TD>
<TD>为Hibernate关联的批量抓取设置默认数量. 
<P><SPAN class=strong>取值</SPAN> 建议的取值为<TT class=literal>4</TT>, <TT class=literal>8</TT>, 和<TT class=literal>16</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.default_entity_mode</TT></TD>
<TD>为由这个<TT class=literal>SessionFactory</TT>打开的所有Session指定默认的实体表现模式. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>dynamic-map</TT>, <TT class=literal>dom4j</TT>, <TT class=literal>pojo</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.order_updates</TT></TD>
<TD>强制Hibernate按照被更新数据的主键，为SQL更新排序。这么做将减少在高并发系统中事务的死锁。 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.generate_statistics</TT></TD>
<TD>如果开启, Hibernate将收集有助于性能调节的统计数据. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.use_identifer_rollback</TT></TD>
<TD>如果开启, 在对象被删除时生成的标识属性将被重设为默认值. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.use_sql_comments</TT></TD>
<TD>如果开启, Hibernate将在SQL中生成有助于调试的注释信息, 默认值为<TT class=literal>false</TT>. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR></TBODY></TABLE></DIV>
<DIV class=table><A name=configuration-jdbc-properties></A>
<P class=title><B>表&nbsp;4.4.&nbsp; Hibernate JDBC和连接(connection)属性 </B></P>
<TABLE summary="&#10;                Hibernate JDBC和连接(connection)属性&#10;            " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>属性名 </TH>
<TH>用途 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>hibernate.jdbc.fetch_size</TT></TD>
<TD>非零值，指定JDBC抓取数量的大小 (调用<TT class=literal>Statement.setFetchSize()</TT>). </TD></TR>
<TR>
<TD><TT class=literal>hibernate.jdbc.batch_size</TT></TD>
<TD>非零值，允许Hibernate使用JDBC2的批量更新. 
<P><SPAN class=strong>取值</SPAN> 建议取<TT class=literal>5</TT>到<TT class=literal>30</TT>之间的值 </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.jdbc.batch_versioned_data</TT></TD>
<TD>如果你想让你的JDBC驱动从<TT class=literal>executeBatch()</TT>返回正确的行计数 , 那么将此属性设为<TT class=literal>true</TT>(开启这个选项通常是安全的). 同时，Hibernate将为自动版本化的数据使用批量DML. 默认值为<TT class=literal>false</TT>. 
<P><SPAN class=strong>eg.</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.jdbc.factory_class</TT></TD>
<TD>选择一个自定义的<TT class=literal>Batcher</TT>. 多数应用程序不需要这个配置属性. 
<P><SPAN class=strong>eg.</SPAN> <TT class=literal>classname.of.Batcher</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.jdbc.use_scrollable_resultset</TT></TD>
<TD>允许Hibernate使用JDBC2的可滚动结果集. 只有在使用用户提供的JDBC连接时，这个选项才是必要的, 否则Hibernate会使用连接的元数据. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.jdbc.use_streams_for_binary</TT></TD>
<TD>在JDBC读写<TT class=literal>binary (二进制)</TT>或<TT class=literal>serializable (可序列化)</TT> 的类型时使用流(stream)(系统级属性). 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.jdbc.use_get_generated_keys</TT></TD>
<TD>在数据插入数据库之后，允许使用JDBC3 <TT class=literal>PreparedStatement.getGeneratedKeys()</TT> 来获取数据库生成的key(键)。需要JDBC3+驱动和JRE1.4+, 如果你的数据库驱动在使用Hibernate的标 识生成器时遇到问题，请将此值设为false. 默认情况下将使用连接的元数据来判定驱动的能力. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true|false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.provider_class</TT></TD>
<TD>自定义<TT class=literal>ConnectionProvider</TT>的类名, 此类用来向Hibernate提供JDBC连接. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>classname.of.ConnectionProvider</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.isolation</TT></TD>
<TD>设置JDBC事务隔离级别. 查看<TT class=literal>java.sql.Connection</TT>来了解各个值的具体意义, 但请注意多数数据库都不支持所有的隔离级别. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>1, 2, 4, 8</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.autocommit</TT></TD>
<TD>允许被缓存的JDBC连接开启自动提交(autocommit) (不建议). 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.release_mode</TT></TD>
<TD>指定Hibernate在何时释放JDBC连接. 默认情况下,直到Session被显式关闭或被断开连接时,才会释放JDBC连接. 对于应用程序服务器的JTA数据源, 你应当使用<TT class=literal>after_statement</TT>, 这样在每次JDBC调用后，都会主动的释放连接. 对于非JTA的连接, 使用<TT class=literal>after_transaction</TT>在每个事务结束时释放连接是合理的. <TT class=literal>auto</TT>将为JTA和CMT事务策略选择<TT class=literal>after_statement</TT>, 为JDBC事务策略选择<TT class=literal>after_transaction</TT>. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>on_close</TT> | <TT class=literal>after_transaction</TT> | <TT class=literal>after_statement</TT> | <TT class=literal>auto</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.connection.<SPAN class=emphasis><EM>&lt;propertyName&gt;</EM></SPAN></TT></TD>
<TD>将JDBC属性<TT class=literal>propertyName</TT>传递到<TT class=literal>DriverManager.getConnection()</TT>中去. </TD></TR>
<TR>
<TD><TT class=literal>hibernate.jndi.<SPAN class=emphasis><EM>&lt;propertyName&gt;</EM></SPAN></TT></TD>
<TD>将属性<TT class=literal>propertyName</TT>传递到JNDI <TT class=literal>InitialContextFactory</TT>中去. </TD></TR></TBODY></TABLE></DIV>
<DIV class=table><A name=configuration-cache-properties></A>
<P class=title><B>表&nbsp;4.5.&nbsp; Hibernate缓存属性 </B></P>
<TABLE summary="&#10;                Hibernate缓存属性&#10;            " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>属性名 </TH>
<TH>用途 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>hibernate.cache.provider_class</TT></TD>
<TD>自定义的<TT class=literal>CacheProvider</TT>的类名. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>classname.of.CacheProvider</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.cache.use_minimal_puts</TT></TD>
<TD>以频繁的读操作为代价, 优化二级缓存来最小化写操作. 在Hibernate3中，这个设置对的集群缓存非常有用, 对集群缓存的实现而言，默认是开启的. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true|false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.cache.use_query_cache</TT></TD>
<TD>允许查询缓存, 个别查询仍然需要被设置为可缓存的. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true|false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.cache.use_second_level_cache</TT></TD>
<TD>能用来完全禁止使用二级缓存. 对那些在类的映射定义中指定<TT class=literal>&lt;cache&gt;</TT>的类，会默认开启二级缓存. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true|false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.cache.query_cache_factory</TT></TD>
<TD>自定义的实现<TT class=literal>QueryCache</TT>接口的类名, 默认为内建的<TT class=literal>StandardQueryCache</TT>. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>classname.of.QueryCache</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.cache.region_prefix</TT></TD>
<TD>二级缓存区域名的前缀. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>prefix</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.cache.use_structured_entries</TT></TD>
<TD>强制Hibernate以更人性化的格式将数据存入二级缓存. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true|false</TT> </P></TD></TR></TBODY></TABLE></DIV>
<DIV class=table><A name=configuration-transaction-properties></A>
<P class=title><B>表&nbsp;4.6.&nbsp; Hibernate事务属性 </B></P>
<TABLE summary="&#10;                Hibernate事务属性&#10;            " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>属性名 </TH>
<TH>用途 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>hibernate.transaction.factory_class</TT></TD>
<TD>一个<TT class=literal>TransactionFactory</TT>的类名, 用于Hibernate <TT class=literal>Transaction</TT> API (默认为<TT class=literal>JDBCTransactionFactory</TT>). 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>classname.of.TransactionFactory</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>jta.UserTransaction</TT></TD>
<TD>一个JNDI名字，被<TT class=literal>JTATransactionFactory</TT>用来从应用服务器获取JTA <TT class=literal>UserTransaction</TT>. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>jndi/composite/name</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.transaction.manager_lookup_class</TT></TD>
<TD>一个<TT class=literal>TransactionManagerLookup</TT>的类名 - 当使用JVM级缓存，或在JTA环境中使用hilo生成器的时候需要该类. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>classname.of.TransactionManagerLookup</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.transaction.flush_before_completion</TT></TD>
<TD>如果开启, session在事务完成后将被自动清洗(flush). (在Hibernate和CMT一起使用时很有用.) 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.transaction.auto_close_session</TT></TD>
<TD>如果开启, session在事务完成后将被自动关闭. (在Hibernate和CMT一起使用时很有用.) 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR></TBODY></TABLE></DIV>
<DIV class=table><A name=configuration-misc-properties></A>
<P class=title><B>表&nbsp;4.7.&nbsp; 其他属性 </B></P>
<TABLE summary="&#10;                其他属性&#10;            " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>属性名 </TH>
<TH>用途 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>hibernate.query.factory_class</TT></TD>
<TD>选择HQL解析器的实现. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>org.hibernate.hql.ast.ASTQueryTranslatorFactory</TT> or <TT class=literal>org.hibernate.hql.classic.ClassicQueryTranslatorFactory</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.query.substitutions</TT></TD>
<TD>将Hibernate查询中的符号映射到SQL查询中的符号 (符号可能是函数名或常量名字). 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.hbm2ddl.auto</TT></TD>
<TD>在<TT class=literal>SessionFactory</TT>创建时，自动将数据库schema的DDL导出到数据库. 使用 <TT class=literal>create-drop</TT>时,在显式关闭<TT class=literal>SessionFactory</TT>时，将drop掉数据库schema. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>update</TT> | <TT class=literal>create</TT> | <TT class=literal>create-drop</TT> </P></TD></TR>
<TR>
<TD><TT class=literal>hibernate.cglib.use_reflection_optimizer</TT></TD>
<TD>开启CGLIB来替代运行时反射机制(系统级属性). 反射机制有时在除错时比较有用. 注意即使关闭这个优化, Hibernate还是需要CGLIB. 你不能在<TT class=literal>hibernate.cfg.xml</TT>中设置此属性. 
<P><SPAN class=strong>取值</SPAN> <TT class=literal>true</TT> | <TT class=literal>false</TT> </P></TD></TR></TBODY></TABLE></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-dialects></A>4.4.1.&nbsp; SQL方言 </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>你应当总是为你的数据库属性<TT class=literal>hibernate.dialect</TT>设置正确的 <TT class=literal>org.hibernate.dialect.Dialect</TT>子类. 如果你指定一种方言, Hibernate将为上面列出的一些属性使用合理的默认值, 为你省去了手工指定它们的功夫. </P>
<DIV class=table><A name=sql-dialects></A>
<P class=title><B>表&nbsp;4.8.&nbsp; Hibernate SQL方言 (<TT class=literal>hibernate.dialect</TT>) </B></P>
<TABLE summary="&#10;                    Hibernate SQL方言 (hibernate.dialect)&#10;                " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>RDBMS</TH>
<TH>方言 </TH></TR></THEAD>
<TBODY>
<TR>
<TD>DB2</TD>
<TD><TT class=literal>org.hibernate.dialect.DB2Dialect</TT></TD></TR>
<TR>
<TD>DB2 AS/400</TD>
<TD><TT class=literal>org.hibernate.dialect.DB2400Dialect</TT></TD></TR>
<TR>
<TD>DB2 OS390</TD>
<TD><TT class=literal>org.hibernate.dialect.DB2390Dialect</TT></TD></TR>
<TR>
<TD>PostgreSQL</TD>
<TD><TT class=literal>org.hibernate.dialect.PostgreSQLDialect</TT></TD></TR>
<TR>
<TD>MySQL</TD>
<TD><TT class=literal>org.hibernate.dialect.MySQLDialect</TT></TD></TR>
<TR>
<TD>MySQL with InnoDB</TD>
<TD><TT class=literal>org.hibernate.dialect.MySQLInnoDBDialect</TT></TD></TR>
<TR>
<TD>MySQL with MyISAM</TD>
<TD><TT class=literal>org.hibernate.dialect.MySQLMyISAMDialect</TT></TD></TR>
<TR>
<TD>Oracle (any version)</TD>
<TD><TT class=literal>org.hibernate.dialect.OracleDialect</TT></TD></TR>
<TR>
<TD>Oracle 9i/10g</TD>
<TD><TT class=literal>org.hibernate.dialect.Oracle9Dialect</TT></TD></TR>
<TR>
<TD>Sybase</TD>
<TD><TT class=literal>org.hibernate.dialect.SybaseDialect</TT></TD></TR>
<TR>
<TD>Sybase Anywhere</TD>
<TD><TT class=literal>org.hibernate.dialect.SybaseAnywhereDialect</TT></TD></TR>
<TR>
<TD>Microsoft SQL Server</TD>
<TD><TT class=literal>org.hibernate.dialect.SQLServerDialect</TT></TD></TR>
<TR>
<TD>SAP DB</TD>
<TD><TT class=literal>org.hibernate.dialect.SAPDBDialect</TT></TD></TR>
<TR>
<TD>Informix</TD>
<TD><TT class=literal>org.hibernate.dialect.InformixDialect</TT></TD></TR>
<TR>
<TD>HypersonicSQL</TD>
<TD><TT class=literal>org.hibernate.dialect.HSQLDialect</TT></TD></TR>
<TR>
<TD>Ingres</TD>
<TD><TT class=literal>org.hibernate.dialect.IngresDialect</TT></TD></TR>
<TR>
<TD>Progress</TD>
<TD><TT class=literal>org.hibernate.dialect.ProgressDialect</TT></TD></TR>
<TR>
<TD>Mckoi SQL</TD>
<TD><TT class=literal>org.hibernate.dialect.MckoiDialect</TT></TD></TR>
<TR>
<TD>Interbase</TD>
<TD><TT class=literal>org.hibernate.dialect.InterbaseDialect</TT></TD></TR>
<TR>
<TD>Pointbase</TD>
<TD><TT class=literal>org.hibernate.dialect.PointbaseDialect</TT></TD></TR>
<TR>
<TD>FrontBase</TD>
<TD><TT class=literal>org.hibernate.dialect.FrontbaseDialect</TT></TD></TR>
<TR>
<TD>Firebird</TD>
<TD><TT class=literal>org.hibernate.dialect.FirebirdDialect</TT></TD></TR></TBODY></TABLE></DIV></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-outerjoin></A>4.4.2.&nbsp; 外连接抓取(Outer Join Fetching) </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>如果你的数据库支持ANSI, Oracle或Sybase风格的外连接, <SPAN class=emphasis><EM>外连接抓取</EM></SPAN>常能通过限制往返数据库次数 (更多的工作交由数据库自己来完成)来提高效率. 外连接允许在单个<TT class=literal>SELECT</TT>SQL语句中， 通过many-to-one, one-to-many, many-to-many和one-to-one关联获取连接对象的整个对象图. </P>
<P>将<TT class=literal>hibernate.max_fetch_depth</TT>设为<TT class=literal>0</TT>能在<SPAN class=emphasis><EM>全局</EM></SPAN> 范围内禁止外连接抓取. 设为<TT class=literal>1</TT>或更高值能启用one-to-one和many-to-oneouter关联的外连接抓取, 它们通过 <TT class=literal>fetch="join"</TT>来映射. </P>
<P>参见<A title="20.1.&nbsp;&#10;&#9;&#10;&#9;&#9;&#9;抓取策略(Fetching strategies)&#10;&#9;&#9;" href="file:///G:/tools/j2ee/hibernate-3.0/doc/reference/zh-cn/html/performance.html#performance-fetching">第&nbsp;20.1&nbsp;节 “ 抓取策略(Fetching strategies) ”</A>获得更多信息. </P></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-binarystreams></A>4.4.3.&nbsp; 二进制流 (Binary Streams) </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>Oracle限制那些通过JDBC驱动传输的<TT class=literal>字节</TT>数组的数目. 如果你希望使用<TT class=literal>二进值 (binary)</TT>或 <TT class=literal>可序列化的 (serializable)</TT>类型的大对象, 你应该开启 <TT class=literal>hibernate.jdbc.use_streams_for_binary</TT>属性. <SPAN class=emphasis><EM>这是系统级属性.</EM></SPAN> </P></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-cacheprovider></A>4.4.4.&nbsp; 二级缓存与查询缓存 </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>以<TT class=literal>hibernate.cache</TT>为前缀的属性允许你在Hibernate中，使用进程或群集范围内的二级缓存系统. 参见<A title="20.2.&nbsp;二级缓存（The Second Level Cache）&#10;&#9;&#9;" href="file:///G:/tools/j2ee/hibernate-3.0/doc/reference/zh-cn/html/performance.html#performance-cache">第&nbsp;20.2&nbsp;节 “二级缓存（The Second Level Cache） ”</A>获取更多的详情. </P></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-querysubstitution></A>4.4.5.&nbsp; 查询语言中的替换 </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>你可以使用<TT class=literal>hibernate.query.substitutions</TT>在Hibernate中定义新的查询符号. 例如: </P><PRE class=programlisting>hibernate.query.substitutions true=1, false=0</PRE>
<P>将导致符号<TT class=literal>true</TT>和<TT class=literal>false</TT>在生成的SQL中被翻译成整数常量. </P><PRE class=programlisting>hibernate.query.substitutions toLowercase=LOWER</PRE>
<P>将允许你重命名SQL中的<TT class=literal>LOWER</TT>函数. </P></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-statistics></A>4.4.6.&nbsp; Hibernate的统计(statistics)机制 </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>如果你开启<TT class=literal>hibernate.generate_statistics</TT>, 那么当你通过 <TT class=literal>SessionFactory.getStatistics()</TT>调整正在运行的系统时，Hibernate将导出大量有用的数据. Hibernate甚至能被配置成通过JMX导出这些统计信息. 参考<TT class=literal>org.hibernate.stats</TT>中接口的Javadoc，以获得更多信息. </P></DIV></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-logging></A>4.5.&nbsp; 日志 </H2></DIV></DIV>
<DIV></DIV></DIV>
<P>Hibernate使用Apache commons-logging来为各种事件记录日志. </P>
<P>commons-logging将直接输出到Apache Log4j(如果在类路径中包括<TT class=literal>log4j.jar</TT>)或 JDK1.4 logging (如果运行在JDK1.4或以上的环境下). 你可以从<TT class=literal>http://jakarta.apache.org</TT> 下载Log4j. 要使用Log4j，你需要将<TT class=literal>log4j.properties</TT>文件放置在类路径下, 随Hibernate 一同分发的样例属性文件在<TT class=literal>src/</TT>目录下. </P>
<P>我们强烈建议你熟悉一下Hibernate的日志消息. 在不失可读性的前提下， 我们做了很多工作，使Hibernate的日志可能地详细. 这是必要的查错利器. 最令人感兴趣的日志分类有如下这些: </P>
<DIV class=table><A name=log-categories></A>
<P class=title><B>表&nbsp;4.9.&nbsp; Hibernate日志类别 </B></P>
<TABLE summary="&#10;                    Hibernate日志类别&#10;                " border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>类别 </TH>
<TH>功能 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>org.hibernate.SQL</TT></TD>
<TD>在所有SQL DML语句被执行时为它们记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.type</TT></TD>
<TD>为所有JDBC参数记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.tool.hbm2ddl</TT></TD>
<TD>在所有SQL DDL语句执行时为它们记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.pretty</TT></TD>
<TD>在session清洗(flush)时，为所有与其关联的实体(最多20个)的状态记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.cache</TT></TD>
<TD>为所有二级缓存的活动记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction</TT></TD>
<TD>为事务相关的活动记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.jdbc</TT></TD>
<TD>为所有JDBC资源的获取记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.hql.ast</TT></TD>
<TD>为HQL和SQL的自动状态转换和其他关于查询解析的信息记录日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.secure</TT></TD>
<TD>为JAAS认证请求做日志 </TD></TR>
<TR>
<TD><TT class=literal>org.hibernate</TT></TD>
<TD>为任何Hibernate相关信息做日志 (信息量较大, 但对查错非常有帮助) </TD></TR></TBODY></TABLE></DIV>
<P>在使用Hibernate开发应用程序时, 你应当总是为<TT class=literal>org.hibernate.SQL</TT> 开启<TT class=literal>debug</TT>级别的日志记录,或者开启<TT class=literal>hibernate.show_sql</TT>属性来代替它。. </P></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-namingstrategy></A>4.6.&nbsp; 实现<TT class=literal>NamingStrategy</TT> </H2></DIV></DIV>
<DIV></DIV></DIV>
<P><TT class=literal>org.hibernate.cfg.NamingStrategy</TT>接口允许你为数据库中的对象和schema 元素指定一个“命名标准”. </P>
<P>你可能会提供一些通过Java标识生成数据库标识或将映射定义文件中"逻辑"表/列名处理成"物理"表/列名的规则. 这个特性有助于减少冗长的映射定义文件. </P>
<P>在加入映射定义前，你可以调用 <TT class=literal>Configuration.setNamingStrategy()</TT>指定一个不同的命名策略: </P><PRE class=programlisting>SessionFactory sf = new Configuration()
    .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
    .addFile("Item.hbm.xml")
    .addFile("Bid.hbm.xml")
    .buildSessionFactory();</PRE>
<P><TT class=literal>org.hibernate.cfg.ImprovedNamingStrategy</TT>是一个内建的命名策略, 对 一些应用程序而言，可能是非常有用的起点. </P></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-xmlconfig></A>4.7.&nbsp; XML配置文件 </H2></DIV></DIV>
<DIV></DIV></DIV>
<P>另一个配置方法是在<TT class=literal>hibernate.cfg.xml</TT>文件中指定一套完整的配置. 这个文件可以当成<TT class=literal>hibernate.properties</TT>的替代。 若两个文件同时存在，它将重载前者的属性. </P>
<P>XML配置文件被默认是放在<TT class=literal>CLASSPATH</TT>的根目录下. 这是一个例子: </P>
<P></P><PRE class=programlisting>&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&gt;

&lt;hibernate-configuration&gt;

    &lt;!-- 以/jndi/name绑定到JNDI的SessionFactory实例 --&gt;
    &lt;session-factory
        name="java:hibernate/SessionFactory"&gt;

        &lt;!-- 属性 --&gt;
        &lt;property name="connection.datasource"&gt;java:/comp/env/jdbc/MyDB&lt;/property&gt;
        &lt;property name="dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/property&gt;
        &lt;property name="show_sql"&gt;false&lt;/property&gt;
        &lt;property name="transaction.factory_class"&gt;
            org.hibernate.transaction.JTATransactionFactory
        &lt;/property&gt;
        &lt;property name="jta.UserTransaction"&gt;java:comp/UserTransaction&lt;/property&gt;

        &lt;!-- 映射定义文件 --&gt;
        &lt;mapping resource="org/hibernate/auction/Item.hbm.xml"/&gt;
        &lt;mapping resource="org/hibernate/auction/Bid.hbm.xml"/&gt;

        &lt;!-- 缓存设置 --&gt;
        &lt;class-cache class="org.hibernate.auction.Item" usage="read-write"/&gt;
        &lt;class-cache class="org.hibernate.auction.Bid" usage="read-only"/&gt;
        &lt;collection-cache class="org.hibernate.auction.Item.bids" usage="read-write"/&gt;

    &lt;/session-factory&gt;

&lt;/hibernate-configuration&gt;</PRE>
<P>如你所见, 这个方法优势在于，在配置文件中指出了映射定义文件的名字. 一旦你需要调整Hibernate的缓存， <TT class=literal>hibernate.cfg.xml</TT>也是更方便. 注意，使用<TT class=literal>hibernate.properties</TT>还是 <TT class=literal>hibernate.cfg.xml</TT>完全是由你来决定, 除了上面提到的XML语法的优势之外, 两者是等价的. </P>
<P>使用XML配置，使得启动Hibernate变的异常简单, 如下所示，一行代码就可以搞定： </P><PRE class=programlisting>SessionFactory sf = new Configuration().configure().buildSessionFactory();</PRE>
<P>你可以使用如下代码来添加一个不同的XML配置文件 </P><PRE class=programlisting>SessionFactory sf = new Configuration()
    .configure("catdb.cfg.xml")
    .buildSessionFactory();</PRE></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=configuration-j2ee></A>4.8.&nbsp; J2EE应用程序服务器的集成 </H2></DIV></DIV>
<DIV></DIV></DIV>
<P>针对J2EE体系,Hibernate有如下几个集成的方面: </P>
<DIV class=itemizedlist>
<UL type=disc>
<LI>
<P><SPAN class=emphasis><EM>容器管理的数据源(Container-managed datasources)</EM></SPAN>: Hibernate能通过容器管理由JNDI提供的JDBC连接. 通常, 特别是当处理多个数据源的分布式事务的时候, 由一个JTA兼容的<TT class=literal>TransactionManager</TT>和一个 <TT class=literal>ResourceManager</TT>来处理事务管理(CMT, 容器管理的事务). 当然你可以通过 编程方式来划分事务边界(BMT, Bean管理的事务). 或者为了代码的可移植性，你也也许会想使用可选的 Hibernate <TT class=literal>Transaction</TT> API. </P></LI></UL></DIV>
<DIV class=itemizedlist>
<UL type=disc>
<LI>
<P><SPAN class=emphasis><EM>自动JNDI绑定</EM></SPAN>: Hibernate可以在启动后将 <TT class=literal>SessionFactory</TT>绑定到JNDI. </P></LI></UL></DIV>
<DIV class=itemizedlist>
<UL type=disc>
<LI>
<P><SPAN class=emphasis><EM>JTA Session绑定:</EM></SPAN> 如果使用EJB, Hibernate <TT class=literal>Session</TT> 可以自动绑定到JTA事务作用的范围. 只需简单地从JNDI查找<TT class=literal>SessionFactory</TT>并获得当前的 <TT class=literal>Session</TT>. 当JTA事务完成时, 让Hibernate来处理 <TT class=literal>Session</TT>的清洗(flush)与关闭. 在EJB的部署描述符中事务边界是声明式的. </P></LI></UL></DIV>
<DIV class=itemizedlist>
<UL type=disc>
<LI>
<P><SPAN class=emphasis><EM>JMX部署:</EM></SPAN> 如果你使用支持JMX应用程序服务器(如, JBoss AS), 那么你可以选择将Hibernate部署成托管MBean. 这将为你省去一行从<TT class=literal>Configuration</TT>构建<TT class=literal>SessionFactory</TT>的启动代码. 容器将启动你的<TT class=literal>HibernateService</TT>, 并完美地处理好服务间的依赖关系 (在Hibernate启动前，数据源必须是可用的等等). </P></LI></UL></DIV>
<P>如果应用程序服务器抛出"connection containment"异常, 根据你的环境，也许该将配置属性 <TT class=literal>hibernate.connection.release_mode</TT>设为<TT class=literal>after_statement</TT>. </P>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-transactionstrategy></A>4.8.1.&nbsp; 事务策略配置 </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>在你的架构中，Hibernate的<TT class=literal>Session</TT> API是独立于任何事务分界系统的. 如果你让Hibernate通过连接池直接使用JDBC, 你需要调用JDBC API来打开和关闭你的事务. 如果你运行在J2EE应用程序服务器中, 你也许想用Bean管理的事务并在需要的时候调用JTA API和<TT class=literal>UserTransaction</TT>. </P>
<P>为了让你的代码在两种(或其他)环境中可以移植，我们建议使用可选的Hibernate <TT class=literal>Transaction</TT> API, 它包装并隐藏了底层系统. 你必须通过设置Hibernate配置属性<TT class=literal>hibernate.transaction.factory_class</TT>来指定 一个<TT class=literal>Transaction</TT>实例的工厂类. </P>
<P>存在着三个标准(内建)的选择: </P>
<DIV class=variablelist>
<DL>
<DT><SPAN class=term><TT class=literal>org.hibernate.transaction.JDBCTransactionFactory</TT></SPAN> 
<DD>
<P>委托给数据库(JDBC)事务（默认） </P>
<DT><SPAN class=term><TT class=literal>org.hibernate.transaction.JTATransactionFactory</TT></SPAN> 
<DD>
<P>如果在上下文环境中存在运行着的事务(如, EJB会话Bean的方法), 则委托给容器管 理的事务, 否则，将启动一个新的事务，并使用Bean管理的事务. </P>
<DT><SPAN class=term><TT class=literal>org.hibernate.transaction.CMTTransactionFactory</TT></SPAN> 
<DD>
<P>委托给容器管理的JTA事务 </P></DD></DL></DIV>
<P>你也可以定义属于你自己的事务策略 (如, 针对CORBA的事务服务) </P>
<P>Hibernate的一些特性 (即二级缓存, JTA与Session的自动绑定等等)需要访问在托管环境中的JTA <TT class=literal>TransactionManager</TT>. 由于J2EE没有标准化一个单一的机制,Hibernate在应用程序服务器中，你必须指定Hibernate如何获得<TT class=literal>TransactionManager</TT>的引用: </P>
<DIV class=table><A name=jtamanagerlookup></A>
<P class=title><B>表&nbsp;4.10.&nbsp;JTA TransactionManagers</B></P>
<TABLE summary="JTA TransactionManagers" border=1>
<COLGROUP>
<COL>
<COL></COLGROUP>
<THEAD>
<TR>
<TH>Transaction工厂类 </TH>
<TH align=middle>应用程序服务器 </TH></TR></THEAD>
<TBODY>
<TR>
<TD><TT class=literal>org.hibernate.transaction.JBossTransactionManagerLookup</TT></TD>
<TD align=middle>JBoss</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.WeblogicTransactionManagerLookup</TT></TD>
<TD align=middle>Weblogic</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.WebSphereTransactionManagerLookup</TT></TD>
<TD align=middle>WebSphere</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</TT></TD>
<TD align=middle>WebSphere 6</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.OrionTransactionManagerLookup</TT></TD>
<TD align=middle>Orion</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.ResinTransactionManagerLookup</TT></TD>
<TD align=middle>Resin</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.JOTMTransactionManagerLookup</TT></TD>
<TD align=middle>JOTM</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.JOnASTransactionManagerLookup</TT></TD>
<TD align=middle>JOnAS</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.JRun4TransactionManagerLookup</TT></TD>
<TD align=middle>JRun4</TD></TR>
<TR>
<TD><TT class=literal>org.hibernate.transaction.BESTransactionManagerLookup</TT></TD>
<TD align=middle>Borland ES</TD></TR></TBODY></TABLE></DIV></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-optional-jndi></A>4.8.2.&nbsp; JNDI绑定的<TT class=literal>SessionFactory</TT> </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>与JNDI绑定的Hibernate的<TT class=literal>SessionFactory</TT>能简化工厂的查询，简化创建新的<TT class=literal>Session</TT>. 需要注意的是这与JNDI绑定<TT class=literal>Datasource</TT>没有关系, 它们只是恰巧用了相同的注册表! </P>
<P>如果你希望将<TT class=literal>SessionFactory</TT>绑定到一个JNDI的名字空间, 用属性<TT class=literal>hibernate.session_factory_name</TT>指定一个名字(如, <TT class=literal>java:hibernate/SessionFactory</TT>). 如果不设置这个属性, <TT class=literal>SessionFactory</TT>将不会被绑定到JNDI中. (在以只读JNDI为默认实现的环境中，这个设置尤其有用, 如Tomcat.) </P>
<P>在将<TT class=literal>SessionFactory</TT>绑定至JNDI时, Hibernate将使用<TT class=literal>hibernate.jndi.url</TT>, 和<TT class=literal>hibernate.jndi.class</TT>的值来实例化初始环境(initial context). 如果它们没有被指定, 将使用默认的<TT class=literal>InitialContext</TT>. </P>
<P>在你调用<TT class=literal>cfg.buildSessionFactory()</TT>后, Hibernate会自动将<TT class=literal>SessionFactory</TT>注册到JNDI. 这意味这你至少需要在你应用程序的启动代码(或工具类)中完成这个调用, 除非你使用<TT class=literal>HibernateService</TT>来做JMX部署 (见后面讨论). </P>
<P>如果你使用与JNDI绑定的<TT class=literal>SessionFactory</TT>, EJB或任何其他类可以通过一个JNDI查询来获得这个<TT class=literal>SessionFactory</TT>. 请注意, 如果你使用第一章中介绍的帮助类<TT class=literal>HibernateUtil</TT> - 类似Singleton(单实例)注册表, 那么这里的启动代码不是必要的. 但<TT class=literal>HibernateUtil</TT>更多被使用在非托管环境中. </P></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-j2ee-currentsession></A>4.8.3.&nbsp; JTA和Session的自动绑定 </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>在非托管环境中，我们建议：<TT class=literal>HibernateUtil</TT>和静态<TT class=literal>SessionFactory</TT>一起工作， 由<TT class=literal>ThreadLocal</TT>管理Hibernate <TT class=literal>Session</TT>。 由于一些EJB可能会运行在同一个事务但不同线程的环境中, 所以这个方法不能照搬到EJB环境中. 我们建议在托管环境中，将<TT class=literal>SessionFactory</TT>绑定到JNDI上. </P>
<P>请使用<TT class=literal>SessionFactory</TT>的<TT class=literal>getCurrentSession()</TT>方法来代替 直接使用<TT class=literal>ThreadLocal</TT>去获得Hibernate <TT class=literal>Session</TT>. 如果在当前JTA事务中没有Hibernate <TT class=literal>Session</TT>, 将会启动一个并将它关联到事务中. 对于使用<TT class=literal>getCurrentSession()</TT>获得的每个<TT class=literal>Session</TT>而言， <TT class=literal>hibernate.transaction.flush_before_completion</TT> 和<TT class=literal>hibernate.transaction.auto_close_session</TT>这两个配置选项会自动设置, 因此在容器结束JTA事务时，这些<TT class=literal>Session</TT>会被自动清洗(flush)并关闭. </P>
<P>例如，如果你使用DAO模式来编写你的持久层, 那么在需要时，所有DAO将查找<TT class=literal>SessionFactory</TT>并打开"当前"Session. 没有必要在控制代码和DAO代码间传递<TT class=literal>SessionFactory</TT>或<TT class=literal>Session</TT>的实例. </P></DIV>
<DIV class=sect2 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H3 class=title><A name=configuration-j2ee-jmx></A>4.8.4.&nbsp; JMX部署 </H3></DIV></DIV>
<DIV></DIV></DIV>
<P>为了将<TT class=literal>SessionFactory</TT>注册到JNDI中<TT class=literal>cfg.buildSessionFactory()</TT>这行代码仍需在某处被执行. 你可在一个<TT class=literal>static</TT>初始化块(像<TT class=literal>HibernateUtil</TT>中的那样)中执行它或将Hibernate部署为一个<SPAN class=emphasis><EM>托管的服务</EM></SPAN>. </P>
<P>为了部署在一个支持JMX的应用程序服务器上，Hibernate和 <TT class=literal>org.hibernate.jmx.HibernateService</TT>一同分发，如Jboss AS。 实际的部署和配置是由应用程序服务器提供者指定的. 这里是JBoss 4.0.x的<TT class=literal>jboss-service.xml</TT>样例: </P><PRE class=programlisting>&lt;?xml version="1.0"?&gt;
&lt;server&gt;

&lt;mbean code="org.hibernate.jmx.HibernateService"
    name="jboss.jca:service=HibernateFactory,name=HibernateFactory"&gt;

    &lt;!-- 必须的服务 --&gt;
    &lt;depends&gt;jboss.jca:service=RARDeployer&lt;/depends&gt;
    &lt;depends&gt;jboss.jca:service=LocalTxCM,name=HsqlDS&lt;/depends&gt;

    &lt;!-- 将Hibernate服务绑定到JNDI --&gt;
    &lt;attribute name="JndiName"&gt;java:/hibernate/SessionFactory&lt;/attribute&gt;

    &lt;!-- 数据源设置 --&gt;
    &lt;attribute name="Datasource"&gt;java:HsqlDS&lt;/attribute&gt;
    &lt;attribute name="Dialect"&gt;org.hibernate.dialect.HSQLDialect&lt;/attribute&gt;

    &lt;!-- 事务集成 --&gt;
    &lt;attribute name="TransactionStrategy"&gt;
        org.hibernate.transaction.JTATransactionFactory&lt;/attribute&gt;
    &lt;attribute name="TransactionManagerLookupStrategy"&gt;
        org.hibernate.transaction.JBossTransactionManagerLookup&lt;/attribute&gt;
    &lt;attribute name="FlushBeforeCompletionEnabled"&gt;true&lt;/attribute&gt;
    &lt;attribute name="AutoCloseSessionEnabled"&gt;true&lt;/attribute&gt;

    &lt;!-- 抓取选项 --&gt;
    &lt;attribute name="MaximumFetchDepth"&gt;5&lt;/attribute&gt;

    &lt;!-- 二级缓存 --&gt;
    &lt;attribute name="SecondLevelCacheEnabled"&gt;true&lt;/attribute&gt;
    &lt;attribute name="CacheProviderClass"&gt;org.hibernate.cache.EhCacheProvider&lt;/attribute&gt;
    &lt;attribute name="QueryCacheEnabled"&gt;true&lt;/attribute&gt;

    &lt;!-- 日志 --&gt;
    &lt;attribute name="ShowSqlEnabled"&gt;true&lt;/attribute&gt;

    &lt;!-- 映射定义文件 --&gt;
    &lt;attribute name="MapResources"&gt;auction/Item.hbm.xml,auction/Category.hbm.xml&lt;/attribute&gt;

&lt;/mbean&gt;

&lt;/server&gt;</PRE>
<P>这个文件是部署在<TT class=literal>META-INF</TT>目录下的, 并会被打包到以<TT class=literal>.sar</TT> (service archive)为扩展名的JAR文件中. 同时，你需要打包Hibernate, 它所需要的第三方库, 你编译好的持久化类及你的映射定义文件打包进同一个文档. 你的企业Bean(一般为会话Bean)可能会被打包成它们自己的JAR文件, 但你也许会将EJB JAR文件一同包含进能独立(热)部署的主服务文档. 咨询JBoss AS文档以了解更多的JMX服务与EJB部署的信息. </P></DIV></DIV></DIV><img src ="http://www.blogjava.net/RR00/aggbug/9559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2005-08-08 12:55 <a href="http://www.blogjava.net/RR00/articles/9559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>