> I'm assuming Node.class is your entity class?
Correct

> I'm using hibernate, so I'm wondering if you are adding an @ID to your
nodeId
Yes, nodeId is the primary key and parentId is a foreignKey which joins
back to the Node table by nodeId

 and if your using a @ManyToOne on your childNodes?
> I don't have the code on me but childNodes is a one to many relationship
via parentId

> I believe I understand the basics to the Tree example now. From what I
gathered, the tree example just builds the node list and stores it in
memory and when TreeModel is call, it just accesses the list via ajax. Am I
understanding this correctly?

Correct

> You stated in an earlier response that your code could be modified to
support Tapestry's ajax request. Do you happen to have any working examples
of how to get the TreeModel to dynamically request the query?

I don't have a working example but I can run you through how I would
implement it.

The tapestry tree component requires a TreeModel and a TreeModel can be
built with
1. DefaultTreeModel
2. ValueEncoder
3. TreeModelAdapter
4. Root node

If you get the TreeModelAdapter sorted, you are well on your way.

Let's say that you are writing a category tree. The table (and entity) are
called Category

public class Category {
   private String categoryId;
   private String label;
   private String parentCategoryId;
   // getters and setters
}

I would suggest writing a wrapper class to hold the isLeaf and hasChildren
values so that we can batch this call and avoid the  n+1 selects problem
that I was discussing earlier

public class CategoryNode {
   private Category category;
   private boolean isLeaf;
   private boolean hasChildren;
   // getters and setters
}

Now, you can write your TreeModelAdapter

public class CategoryTreeModelAdapter implements
TreeModelAdapter<CategoryNode> {
   public List<CategoryNode> getChildren(CategoryNode node) {
      List<Category> categories =
getSession().createCriteria(Category.class).add(Restrictions.eq("parentCategoryId",
node.getCategoryId()));

      Map<String, CategoryNode> nodes = new HashMap();
      for (Category category : categories) {
         CategoryNode node = new CategoryNode();
         node.setCategory(category);
         nodes.put(category.getCategoryId(), category);
      }

      // for each of node's children, count the number of children (ie
node's grandchildren)
      // my hibernate is a bit rusty so this might need to be tweaked
      List<Object[]> results = getSession().createSqlQuery(
         "select c1.categoryId, count(c2.*) from Category c1 " +
          "join Category c2 on c2.parentId = c1.categoryId " +
          "where c1.parentId = ? " +
          "group by c1.categoryId",
          node.getCategoryId()
      ).list();
      for (Object[] result : results) {
         String childId = (String) result[0];
         int grandChildCount = (Integer) result[1];
         CategoryNode childNode = nodes.get(childId);
         childNode.setIsLeaf(grandChildCount == 0);
         childNode.setHasChildren(grandChildCount != 0);
      }
      return new ArrayList(nodes.values());
   }

   public String getLabel(CategoryNode node) {
      return node.getCategory().getLabel();
   }

   public boolean hasChildren(CategoryNode node) {
      return node.hasChildren(); // since this was determined in a single
query, we have avoided the n+1 selects problem

   }

   boolean isLeaf(CategoryNode node) {
      return node.isLeaf(); // since this was determined in a single query,
we have avoided the n+1 selects problem
   }
}

That should get you well on the way and then you will just need to write a
ValueEncoder<CategoryNode> and also find the root.

I would suggest moving the hibernate logic into a dao which can be shared
by CategoryTreeModelAdapter, ValueEncoder and your page (to find the root)

Cheers,
Lance.

On Friday, 10 February 2012, George Christman <gchrist...@cardaddy.com>
wrote:
> Hi Lance, I'm just getting back to this project and have come up with a
few
> more questions.
>
> I'm assuming node.class is your entity class? I'm using hibernate, so I'm
> wondering if you are adding an @ID to your nodeId and if your using a
> @ManyToOne on your childNodes?
>
> I believe I understand the basics to the Tree example now. From what I
> gathered, the tree example just builds the node list and stores it in
memory
> and when TreeModel is call, it just accesses the list via ajax. Am I
> understanding this correctly?
>
> You stated in an earlier response that your code could be modified to
> support Tapestry's ajax request. Do you happen to have any working
examples
> of how to get the TreeModel to dynamically request the query?
>
> Thanks Lance
>
> --
> View this message in context:
http://tapestry.1045711.n5.nabble.com/Tapestry-TreeGrid-tp5462126p5471508.html
> Sent from the Tapestry - User mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

Reply via email to