title: Efficient representation of Hierarchies in Hibernate
body: <p>I'm having some trouble representing an object hierarchy in Hibernate.  I've searched around, and haven't managed to find any examples doing this or similar - you have my apologies if this is a common question.</p>
  
  <p>I have two types which I'd like to persist using Hibernate: Groups and Items.<br>
  * Groups are identified uniquely by a combination of their name and their parent.<br>
  * The groups are arranged in a number of trees, such that every Group has zero or one parent Group.<br>
  * Each Item can be a member of zero or more Groups.  </p>
  
  <p>Ideally, I'd like a bi-directional relationship allowing me to get:<br>
  * all Groups that an Item is a member of<br>
  * all Items that are a member of a particular Group or its descendants.<br>
  I also need to be able to traverse the Group tree from the top in order to display it on the UI.</p>
  
  <p>The basic object structure would ideally look like this:</p>
  
  <pre><code>class Group {
      ...
      /** @return all items in this group and its descendants */
      Set&lt;Item&gt; getAllItems() { ... }
  
      /** @return all direct children of this group */
      Set&lt;Group&gt; getChildren() { ... }
      ...
  }
  
  class Item {
      ...
      /** @return all groups that this Item is a direct member of */
      Set&lt;Group&gt; getGroups() { ... }  
      ...
  }
  </code></pre>
  
  <p>Originally, I had just made a simple bi-directional many-to-many relationship between Items and Groups, such that fetching all items in a group hierarchy required recursion down the tree, and fetching groups for an Item was a simple getter, i.e.:</p>
  
  <pre><code>class Group {
      ...
      private Set&lt;Item&gt; items;
      private Set&lt;Group&gt; children;
      ...
      /** @return all items in this group and its descendants */
      Set&lt;Item&gt; getAllItems() {
          Set&lt;Item&gt; allItems = new HashSet&lt;Item&gt;();
          allItems.addAll(this.items);
          for(Group child : this.getChildren()) {
              allItems.addAll(child.getAllItems());
          }
          return allItems;
      }
  
      /** @return all direct children of this group */
      Set&lt;Group&gt; getChildren() {
          return this.children;
      }
      ...
  }
  
  class Item {
      ...
      private Set&lt;Group&gt; groups;
      /** @return all groups that this Item is a direct member of */
      Set&lt;Group&gt; getGroups() {
          return this.groups;
      }
      ...
  }
  </code></pre>
  
  <p>However, this resulted in multiple database requests to fetch the Items in a Group with many descendants, or for retrieving the entire Group tree to display in the UI.  This seems very inefficient, especially with deeper, larger group trees.
  Is there a better or standard way of representing this relationship in Hibernate?</p>
  
  <p>Am I doing anything obviously wrong or stupid?  </p>
  
  <hr/> 
  
  <p>My only other thought so far was this:
  Replace the group's id, parent and name fields with a unique "path" String which specifies the whole ancestry of a group, e.g.:<br>
  /rootGroup<br>
  /rootGroup/aChild<br>
  /rootGroup/aChild/aGrandChild  </p>
  
  <p>The join table between Groups and Items would then contain group_path and item_id.</p>
  
  <p>This immediately solves the two issues I was suffering previously:<br>
  1. The entire group hierarchy can be fetched from the database in a single query and reconstructed in-memory.<br>
  2. To retrieve all Items in a group or its descendants, we can select from group_item where group_path='N' or group_path like 'N/%'  </p>
  
  <p>However, this seems to defeat the point of using Hibernate.  All thoughts welcome!</p>