You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs@cocoon.apache.org by do...@cocoon.apache.org on 2004/11/10 14:11:47 UTC

[Cocoon Wiki] Updated: GettingStartedWithCocoonAndHibernate

   Date: 2004-11-10T05:11:46
   Editor: JohannesTextor <jc...@gmx.de>
   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"].