﻿<?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-谈笑有鸿儒，往来无白丁-文章分类-Hibernate</title><link>http://www.blogjava.net/badboyryan/category/20400.html</link><description>&lt;hr color=red&gt;
&lt;marquee  direction=left bgcolor= aaaaee behavior=scroll scrollamount=2 onmouseover="this.stop();" onmouseout="this.start();" width=500&gt;
&lt;font color=green&gt; 在恰当的时间、地点以恰当的方式表达给恰当的人...&lt;/font&gt;&amp;nbsp;&amp;nbsp;&lt;font color=blue&gt;阅读的时候请注意分类，佛曰我日里面是谈笑文章，其他是各个分类的文章，积极的热情投入到写博的队伍中来，支持blogjava做大做强！向dudu站长致敬&gt;&gt; &gt;  （qq群侠客岛:26858781）&lt;/font&gt;
&lt;/marquee&gt; 
&lt;hr color=blue&gt;
&lt;marquee  direction=right bgcolor= aabbee behavior=scroll scrollamount=2 onmouseover="this.stop();" onmouseout="this.start();" width=500&gt;
&lt;font color=green&gt;精品推荐:&lt;/font&gt;&lt;a href="http://www.blogjava.net/badboyryan/category/13259.html"&gt;谈笑有鸿儒&lt;/a&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=green&gt;&lt;a href="http://www.blogjava.net/badboyryan/category/14653.html"&gt;&lt;font color=red&gt;资源整合，门户网站&lt;/font&gt;&lt;/a&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;
&lt;a href="http://www.blogjava.net/badboyryan/category/15148.html"&gt;JAVA名人堂&lt;/a&gt;
&lt;/marquee&gt; 
&lt;hr color=red&gt;</description><language>zh-cn</language><lastBuildDate>Wed, 07 Mar 2007 17:28:58 GMT</lastBuildDate><pubDate>Wed, 07 Mar 2007 17:28:58 GMT</pubDate><ttl>60</ttl><item><title> 延迟初始化错误（ERROR LazyInitializer）是如何产生的? </title><link>http://www.blogjava.net/badboyryan/articles/102144.html</link><dc:creator>坏男孩</dc:creator><author>坏男孩</author><pubDate>Tue, 06 Mar 2007 06:08:00 GMT</pubDate><guid>http://www.blogjava.net/badboyryan/articles/102144.html</guid><wfw:comment>http://www.blogjava.net/badboyryan/comments/102144.html</wfw:comment><comments>http://www.blogjava.net/badboyryan/articles/102144.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/badboyryan/comments/commentRss/102144.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/badboyryan/services/trackbacks/102144.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<font size="2">选自&lt;&lt;精通Hibernate：Java对象持久化技术详解&gt;&gt; 作者：<a href="http://www.javathinker.org/main.jsp?bc=weiqin/weiqin.jsp">孙卫琴</a> 来源:www.javathinker.org<br />如果转载，请标明出处，谢谢</font>
				<br />
				<br />
				<p>延迟初始化错误是运用Hibernate开发项目时最常见的错误。如果对一个类或者集合配置了延迟检索策略，那么必须当代理类实例或代理集合处于持久化状态（即处于Session范围内）时，才能初始化它。如果在游离状态时才初始化它，就会产生延迟初始化错误。</p>
				<p>下面把Customer.hbm.xml文件的&lt;class&gt;元素的lazy属性设为true，表示使用延迟检索策略：</p>
				<p>&lt;class name="mypack.Customer" table="CUSTOMERS" lazy="true"&gt;</p>
				<p>当执行Session的load()方法时，Hibernate不会立即执行查询CUSTOMERS表的select语句，仅仅返回Customer类的代理类的实例，这个代理类具由以下特征：</p>
				<p>（1） 由Hibernate在运行时动态生成，它扩展了Customer类，因此它继承了Customer类的所有属性和方法，但它的实现对于应用程序是透明的。<br />（2） 当Hibernate创建Customer代理类实例时，仅仅初始化了它的OID属性，其他属性都为null，因此这个代理类实例占用的内存很少。<br />（3） 当应用程序第一次访问Customer代理类实例时（例如调用customer.getXXX()或customer.setXXX()方法）， Hibernate会初始化代理类实例，在初始化过程中执行select语句，真正从数据库中加载Customer对象的所有数据。但有个例外，那就是当 应用程序访问Customer代理类实例的getId()方法时，Hibernate不会初始化代理类实例，因为在创建代理类实例时OID就存在了，不必 到数据库中去查询。<br /><br /><em>提 示：Hibernate采用CGLIB工具来生成持久化类的代理类。CGLIB是一个功能强大的Java字节码生成工具，它能够在程序运行时动态生成扩展 Java类或者实现Java接口的代理类。关于CGLIB的更多知识，请参考：http://cglib.sourceforge.net/。</em></p>
				<p>以下代码先通过Session的load()方法加载Customer对象，然后访问它的name属性： </p>
				<p>tx = session.beginTransaction();<br />Customer customer=(Customer)session.load(Customer.class,new Long(1));<br />customer.getName();<br />tx.commit();</p>
				<p>在 运行session.load()方法时Hibernate不执行任何select语句，仅仅返回Customer类的代理类的实例，它的OID为1，这 是由load()方法的第二个参数指定的。当应用程序调用customer.getName()方法时，Hibernate会初始化Customer代理 类实例，从数据库中加载Customer对象的数据，执行以下select语句：</p>
				<p>select * from CUSTOMERS where ID=1;<br />select * from ORDERS where CUSTOMER_ID=1;</p>
				<p>当&lt;class&gt;元素的lazy属性为true，会影响Session的load()方法的各种运行时行为，下面举例说明。</p>
				<p>1．如果加载的Customer对象在数据库中不存在，Session的load()方法不会抛出异常，只有当运行customer.getName()方法时才会抛出以下异常：</p>
				<p>ERROR LazyInitializer:63 - Exception initializing proxy<br />net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class: <br />mypack.Customer</p>
				<p>2．如果在整个Session范围内，应用程序没有访问过Customer对象，那么Customer代理类的实例一直不会被初始化，Hibernate不会执行任何select语句。以下代码试图在关闭Session后访问Customer游离对象：</p>
				<p>tx = session.beginTransaction();<br />Customer customer=(Customer)session.load(Customer.class,new Long(1));<br />tx.commit();<br />session.close();<br />customer.getName();</p>
				<p>由于引用变量customer引用的Customer代理类的实例在Session范围内始终没有被初始化，因此在执行customer.getName()方法时，Hibernate会抛出以下异常：</p>
				<p>ERROR LazyInitializer:63 - Exception initializing proxy<br />net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed</p>
				<p>由此可见，Customer代理类的实例只有在当前Session范围内才能被初始化。</p>
				<p>3．net.sf.hibernate.Hibernate类的initialize()静态方法用于在Session范围内显式初始化代理类实例，isInitialized()方法用于判断代理类实例是否已经被初始化。例如：</p>
				<p>tx = session.beginTransaction();<br />Customer customer=(Customer)session.load(Customer.class,new Long(1));<br />if(!Hibernate.isInitialized(customer)) <br />Hibernate.initialize(customer);<br />tx.commit();<br />session.close();<br />customer.getName();</p>
				<p>以上代码在Session范围内通过Hibernate类的initialize()方法显式初始化了Customer代理类实例，因此当Session关闭后，可以正常访问Customer游离对象。</p>
				<p>4．当应用程序访问代理类实例的getId()方法时，不会触发Hibernate初始化代理类实例的行为，例如：</p>
				<p>tx = session.beginTransaction();<br />Customer customer=(Customer)session.load(Customer.class,new Long(1));<br />customer.getId();<br />tx.commit();<br />session.close();<br />customer.getName();</p>
				<p>当 应用程序访问customer.getId()方法时，该方法直接返回Customer代理类实例的OID值，无需查询数据库。由于引用变量 customer始终引用的是没有被初始化的Customer代理类实例，因此当Session关闭后再执行customer.getName()方法， Hibernate会抛出以下异常：</p>ERROR LazyInitializer:63 - Exception initializing proxy<br />net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed<br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=656003</p></div>
<img src ="http://www.blogjava.net/badboyryan/aggbug/102144.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/badboyryan/" target="_blank">坏男孩</a> 2007-03-06 14:08 <a href="http://www.blogjava.net/badboyryan/articles/102144.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>