Date: 2004-11-10T05:11:46
   Editor: JohannesTextor <[EMAIL PROTECTED]>
   Wiki: Cocoon Wiki
   Page: GettingStartedWithCocoonAndHibernate
   URL: http://wiki.apache.org/cocoon/GettingStartedWithCocoonAndHibernate

   Trivial stuff about lazy collections after experiencing performance hell 

Change Log:

------------------------------------------------------------------------------
@@ -121,6 +121,82 @@
 
 == Performance Tuning and Optimum Configuration ==
 
+=== Lazy Collection Fetching === 
+
+Lazy Collection Fetching is extremely important to ensure decent performance 
of your Hibernate application. By Default, 
+when fetching an object from the database, Hibernate makes sure that every 
other object reachable via getter methods is 
+also available. 
+
+Suppose you have an article object. Each article has a vector of related 
articles so users can comfortably browse to your 
+store. The following java snippet illustrates this: 
+
+{{{
+
+ import java.util.List
+
+ public class Article{ 
+   ... 
+   private List relatedArticles;
+   ...
+
+   public List getRelatedArticles()
+   {
+      return relatedArticles;
+   }
+ } 
+
+}}}
+
+The corresponding fragment of your mapping file setup straight forward might 
look like this: 
+
+{{{
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 
2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd";>
+<hibernate-mapping>
+  <class name="Article" table="Article">
+    <id name="id" type="long" column="id">
+      <generator class="native" />
+    </id>
+    
+    ....
+
+    <list name="relatedArticles" table="Article_Relations">
+      <key column="articleId" />
+      <index column="rank" />
+      <many-to-many column="relatedId"
+      class="Article" />
+    </list>
+
+    ...     
+
+  </class>
+</hibernate-mapping>
+}}}
+
+
+Now suppose you have five Articles in your database, say A,B,C,D,E. A links to 
B and D while B links to C and D links to E.
+If you use hibebernate to fetch Article A from the database, it will also 
fetch ''all other Articles,'' since you could theoretically
+navigate to all of them using getter methods, i.e. you could reference Article 
E by typing 
+
+Article E = A.getRelatedArticles().get(1).getRelatedArticles().get(0); 
+
+This can be useful if you know that you are going to use all or most articles 
anyway. But in almost every case where you do
+not need to access your entire database at once (which is almost every use 
case I could imagine) it will be useless and lead
+to dramatic performance loss. 
+
+The solution is called Lazy Collection Initialization. This Hibernate feature 
basically leaves all elements in Lists, Maps and other 
+collections uninitialized until the element is actually accessed via get() or 
similar  methods. To turn it on, simply set the attribute
+"lazy" of the respective collection to "true": 
+
+{{{ <list name="relatedArticles" table="Article_Relations" lazy="true"> }}}
+
+If you, like me, programmed a whole webapp without knowing about this feature, 
try it out and see that it will do wonders on 
+overall performance :) Now, when fetching article A, it will only fetch 
article A. If, and only if, you acess article B via the
+relatedArticles List, it will connect to the DB again and fetch it 
dynamically. For this to work, ensure your Hibernate Session is left
+open until you have entirely finished working with your business objects.  
+
+=== Query Caching === 
+
 == Rich Application Interface ==
 
 The adoption of a RAI such Laszlo ([http://www.laszlosystems.com/]) will 
enable you to create a graphically-rich front-end for your web application.  
Please refer to ["Getting Started with Cocoon and Hibernate and Laszlo"].