Hi Lance, I'd like to share my progress with you. I think it will work once we get the hibernate sql query corrected. If you wouldn't mind taking a brief look at my classes to be sure I implemented everything correctly, it would be greatly appreciated. I could always get a little assistance from the hibernate guys too if we can't figure out that query. I seen a ? in the question stringbuilder method. Is that a place holder or is there some kind of logic behind it. Once again thanks,
Cheers, George @Entity public class Category extends BaseEntity { private String label; @OneToMany(mappedBy = "parentCategoryId") private List<Category> children; @ManyToOne @JoinColumn(name = "parent_id") private Category parentCategoryId; //Getters Setters public class CategoryNode { private Category category; private boolean isLeaf; private boolean hasChildren; //Getters Setters public class HibernateCategoryDao implements CategoryDao { private final Session session; public HibernateCategoryDao(Session session) { this.session = session; } // this will be called by ValueEncoder.toValue(id) public CategoryNode findById(String id) { return findByCriterion(Restrictions.eq("categoryId", id)).iterator().next(); } // this will be called by TreeModelAdapter.getChildren(CategoryNode node) public List<CategoryNode> getChildren(CategoryNode node) { return findByCriterion(Restrictions.eq("parentCategoryId", node.getCategory())); } // this will be called by your page public List<CategoryNode> findRoots() { return findByCriterion(Restrictions.isNull("parentCategoryId")); } @SuppressWarnings("unchecked") protected List<CategoryNode> findByCriterion(Criterion criterion) { List<Category> cats = session.createCriteria(Category.class).add(criterion).list(); Map<Integer, CategoryNode> childNodes = new LinkedHashMap<Integer, CategoryNode>(); for (Category cat : cats) { CategoryNode childNode = new CategoryNode(); childNode.setCategory(cat); childNodes.put(cat.getId(), childNode); } StringBuilder questions = new StringBuilder(); for (int i = 0; i < childNodes.size(); ++i) { if (i != 0) { questions.append(", "); } questions.append("?"); } Query query = session.createSQLQuery( "select c1.id, count(c2.*) " + "from Category c1 " + "left join Category c2 on c2.parentCategoryId = c1.id " + "where c1.id in (" + questions + ") " + "group by c1.id"); int i = 0; for (Iterator<CategoryNode> it = childNodes.values().iterator(); i < childNodes.size(); ++i) { query.setLong(i + 1, it.next().getCategory().getId()); } for (Iterator<Object[]> it = query.iterate(); it.hasNext();) { Object[] result = it.next(); Integer childId = (Integer) result[0]; Integer grandChildCount = (Integer) result[1]; CategoryNode childNode = childNodes.get(childId); childNode.setHasChildren(grandChildCount != 0); childNode.setIsLeaf(grandChildCount == 0); } return new ArrayList<CategoryNode>(childNodes.values()); } } public interface CategoryDao { public CategoryNode findById(String id); public List<CategoryNode> getChildren(CategoryNode node); public List<CategoryNode> findRoots(); } public class CategoryTreeModelAdapter implements TreeModelAdapter<CategoryNode> { private HibernateCategoryDao hibernateCategoryDao; public CategoryTreeModelAdapter(HibernateCategoryDao hibernateCategoryDao) { this.hibernateCategoryDao = hibernateCategoryDao; } public List<CategoryNode> getChildren(CategoryNode node) { return hibernateCategoryDao.getChildren(node); } public boolean isLeaf(CategoryNode node) { return node.isLeaf(); } public boolean hasChildren(CategoryNode node) { return node.hasChildren(); } public String getLabel(CategoryNode node) { return node.getCategory().getLabel(); } } public class Tree { @Inject private Session session; private HibernateCategoryDao hibernateCategoryDao; void setupRender() { hibernateCategoryDao = new HibernateCategoryDao(session); } public TreeModel getModel() { return getTreeModel(); } private TreeModel<CategoryNode> treeModel; public TreeSelectionModel getSelectModel(){ return new DefaultTreeSelectionModel(); } public TreeModel<CategoryNode> getTreeModel() { if (treeModel == null) { ValueEncoder<CategoryNode> encoder = new ValueEncoder<CategoryNode>() { @Override public String toClient(CategoryNode node) { return node.getCategory().getId().toString(); } @Override public CategoryNode toValue(String node) { return hibernateCategoryDao.findById(node); } }; treeModel = new DefaultTreeModel<CategoryNode>(encoder, new CategoryTreeModelAdapter(hibernateCategoryDao), hibernateCategoryDao.findRoots()); } return treeModel; } } Tree.tml t:tree t:model="model" t:selectionModel="selectModel"/> -- View this message in context: http://tapestry.1045711.n5.nabble.com/Tapestry-TreeGrid-tp5462126p5488350.html Sent from the Tapestry - User mailing list archive at Nabble.com.