Hibernate的hbm.xml文件中的property元素中的lazy属性。这个百度上搜的结果里说的挺少的,其实主要也是基本上用不到,不过犯了钻牛角尖的臭毛病,就研究了一下。在hibernate下载的文档中对其的描述是:lazy(可选 — 默认为 false):指定 指定实例变量第一次被访问时,这个属性是否延迟抓取(fetched lazily)( 需要运行时字节码增强)。但这个没看太明白,后来在GOOGLE上很容易找到了JBOSS官网上关于这个问题的描述,网址:http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-fetching-lazyproperties
19.1.7. Using lazy property fetching
Hibernate3 supports the lazy fetching of individual properties. This optimization technique is also known as fetch groups. Please note that this is mostly a marketing feature; optimizing row reads is much more important than optimization of column reads. However, only loading some properties of a class could be useful in extreme cases. For example, when legacy tables have hundreds of columns and the data model cannot be improved.
To enable lazy property loading, set the lazy attribute on your particular property mappings:
<class name=”Document”>
<id name=”id”>
<generator/>
</id>
<property name=”name” not-null=”true” length=”50″/>
<property name=”summary” not-null=”true” length=”200″ lazy=”true”/>
<property name=”text” not-null=”true” length=”2000″ lazy=”true”/>
</class>
Lazy property loading requires buildtime bytecode instrumentation. If your persistent classes are not enhanced, Hibernate will ignore lazy property settings and return to immediate fetching.
For bytecode instrumentation, use the following Ant task:
<target name=”instrument” depends=”compile”>
<taskdef name=”instrument” classname=”org.hibernate.tool.instrument.InstrumentTask”>
<classpath path=”${jar.path}”/>
<classpath path=”${classes.dir}”/>
<classpath refid=”lib.class.path”/>
</taskdef>
<instrument verbose=”true”>
<fileset dir=”${testclasses.dir}/org/hibernate/auction/model”>
<include name=”*.class”/>
</fileset>
</instrument>
</target>
A different way of avoiding unnecessary column reads, at least for read-only transactions, is to use the projection features of HQL or Criteria queries. This avoids the need for buildtime bytecode processing and is certainly a preferred solution.
You can force the usual eager fetching of properties using fetch all properties in HQL.
这个就是说要使property中的lazy属性生效,得使用ant,在其中配置 org.hibernate.tool.instrument.InstrumentTask 的字节码增强的工具才能生效,否则lazy属性是无效的。所以文档的最后说比起这个方法,使用 the projection features of HQL or Criteria queries要更为的好,因为它避免了在编译后要对持久化类的class文件进行字节码处理。
我自己后来试验了一下, 当class的lazy设成true的时候,property的lazy属性是没有作用的。都只能是延迟加载。但是当class的lazy设成false的时候,在load的时候,lazy设成true的属性就不会写进select的语句,只有在第一次访问该对像的这个属性的时候,才会执行相应的select的语句取得这个属性的值。
另外要说的一点是,我的hibernate版本是3.6.0.CR2,使用的hibernate的字节码的ant配置跟jboss官网上给出的稍有不同,这个用winrar打开hibernate3.jar文件找到相应的包,在相应的位置并没有文档中的提到的那个InstrumentTask类,我的配置用的是org.hibernate.tool.instrument.javassist.InstrumentTask,在我的hibernate的org.hibernate.tool.instrument包里还有另外一个cglib的包,那里面的InstrumentTask好像已经过时运行的时候会产生错误。