Hello Hibernate Users
I'm still using Hibernate 2.1.8 but I would appreciate replies telling me if my problem is something Hibernate 3 solves.
I have a tree data structure with 1 to many mappings from parents to children where children can also be parents etc. The hbm file is as following:
Code:
<hibernate-mapping>
<class name="TreeNode" table="tree_node">
<cache usage="nonstrict-read-write"/>
<id name="id">
<generator class="assigned"/>
</id>
<property name="name" length="255" not-null="true"/>
<!--
Lots of properties and other relationships omitted for clarity...
-->
<many-to-one name="parent" column="parent_id" not-null="false"/>
<list name="children" cascade="none">
<cache usage="nonstrict-read-write"/>
<key column="parent_id" />
<index type="integer">
<column name="page_index" not-null="false"/>
</index>
<one-to-many class="TreeNode"/>
</list>
</class>
</hibernate-mapping>
This solution seemed to do the job quite nicely. The caching makes it so that when recursively traversing the tree and rendering the contents database access is minimal. This data is not frequently changed it seems pretty much the whole tree structure is stored in the cache (this is fine).
The problem comes when multiple users start accessing the data. What seems to happen is that for each Session, Hibernate returns separate instances of all the classes so that for each user requesting the tree or part of it there is a whole other instance of the complete tree in memory. For large tree's this runs out of memory on JVM's with a gigabyte of max memory. This is at least what I think is going on, the profiler tells me 90% of the memory is used for TreeNode objects.
Making the list of children lazy and removing the cache solves the memory issue, but will result in N sql queries for traversing a N node tree, which is way to slow.
Is there a way I can set this up so that I get the speed benefit of using the cache but not eat up all the memory?
Cheers!
Sindri