-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Large graph with serveral collections woes...
PostPosted: Thu Sep 16, 2004 4:53 pm 
Regular
Regular

Joined: Tue Dec 09, 2003 2:39 pm
Posts: 106
Location: Toronto, Canada
Problem Description

Our use case requires that we build a tree of our entity, Subject, and pass it all the way to our rich client. Subject has four collection associations which need to be fetched/initialized for the tree to be complete.

The Subject mapping follows, however, the collections which require initialization are names (an internationalizable Map of Subject names), children (composite Subject leaf nodes), parentsIds (poorly named legacy association), and attributes. We do not require descriptions in our tree.

We'd like for our DAO to fetch the whole graph prior to sending it to the assembler. Otherwise we run into the N+1 select problem because our assembler will have to navigate the graph and for each child will issue a select statement.

As we understand it this is unavoidable because you can only eager fetch one collection per HQL or Criteria query.

Question

Our question is how're others doing this for similar use cases with multiple collections that require fetching? Is walking the tree the best way?

In HiA step 2 in solving the N+1 select problem involves:

Quote:
Navigate the object graph, which will consist entirely of objects that have already been fetched from the database.

This assumes that all data is fetched in the initial query. How is this possible if eager fetching is understandably limited to one collection per query?

Currently our DAO looks something like this:

Code:
...
subject = (Subject) session.createCriteria(Subject.class)
            .add( Expression.eq("id", (String) root.getId()))
            .setFetchMode("children", FetchMode.EAGER)
            .uniqueResult();
...


we then assemble the tree within the same session. We've read all the performance docs and the HiA chapters on optimizing object retrieval. Just want to be confident that this is the best approach. We're about to attempt batch-fetching, but consider this mapping dangerous as Subject has many other use-case clients...

More details provided upon request.

Regards,
Roll

Subject mapping:

Code:
<hibernate-mapping>
    <class
        name="com.casebank.spotlight.domain.Subject"
        table="subject"
        dynamic-update="false"
        dynamic-insert="false"
        select-before-update="false"
    >

        <cache usage="read-write" />

        <id
            name="id"
            column="id"
            type="java.lang.String"
            unsaved-value="0"
        >
            <generator class="uuid.hex">
              <!-- 
                  To add non XDoclet generator parameters, create a file named
                  hibernate-generator-params-Subject.xml
                  containing the additional parameters and place it in your merge dir.
              -->
            </generator>
        </id>

        <map
            name="names"
            table="subject_name"
            lazy="true"
            sort="unsorted"
            inverse="false"
            cascade="all"
        >
            <cache
                usage="nonstrict-read-write"
             />

              <key
                  column="subject_id"
              >
              </key>

              <index
                  column="locale_id"
                  type="string"
              />

              <element
                  column="translation"
                  type="string"
                  not-null="false"
                  unique="false"
              />

        </map>

        <map
            name="descriptions"
            table="subject_description"
            lazy="true"
            sort="unsorted"
            inverse="false"
            cascade="all"
        >
            <cache
                usage="nonstrict-read-write"
             />

              <key
                  column="subject_id"
              >
              </key>

              <index
                  column="locale_id"
                  type="string"
              />

              <element
                  column="translation"
                  type="string"
                  not-null="false"
                  unique="false"
              />

        </map>

        <list
            name="children"
            table="subject_hierarchy"
            lazy="true"
            inverse="false"
            cascade="none"
        >
            <cache
                usage="nonstrict-read-write"
             />

              <key
                  column="parent_id"
              >
              </key>

              <index
                  column="sort_order"
              />

              <many-to-many
                  class="com.casebank.spotlight.domain.Subject"
                  column="child_id"
                  outer-join="false"
               />

        </list>

        <bag
            name="parentsIds"
            table="subject_hierarchy"
            lazy="true"
            inverse="false"
            cascade="none"
        >
            <cache
                usage="nonstrict-read-write"
             />

              <key
                  column="child_id"
              >
              </key>

              <element
                  column="parent_id"
                  type="string"
                  not-null="false"
                  unique="false"
              />

        </bag>

        <list
            name="attributes"
            table="subject_attribute"
            lazy="true"
            inverse="false"
            cascade="none"
        >
            <cache
                usage="nonstrict-read-write"
             />

              <key
                  column="subject_id"
              >
              </key>

              <index
                  column="sort_order"
              />

              <many-to-many
                  class="com.casebank.spotlight.domain.Attribute"
                  column="attribute_id"
                  outer-join="false"
               />

        </list>

        <!--
            To add non XDoclet property mappings, create a file named
                hibernate-properties-Subject.xml
            containing the additional properties and place it in your merge dir.
        -->

    </class>

</hibernate-mapping>


Hibernate Version: 2.1.6
DB: MS SQL Server 2000


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.