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"].