Thanks Lance, I'll read through those articles this weekend. I'd love to learn more about these things so I wouldn't need to rely so heavily on the support of the community.
I did want to say I finally got the tree to work yay!! A few changes that had to be made public List<CategoryNode> getChildren(CategoryNode node) { return findByCriterion(Restrictions.eq("parentCategoryId.id", node.getCategory().getId())); } I needed to add ".id" to the restriction. When ever your using createSQLQuery, you can directly iterate it. You'll need to use a .list() be for using iterator. I did end up getting the tapestry service working, apparently my issue had to do with me trying to inject HibernateCategoryDao rather than CategoryDao. I was unable to @Inject CateogryDao into CategoryTreeModelAdapter, I had to pass it in through a constructor. Is there away to use Inject outside of page and component classes? Lastly, one remaining bug thus far, when ever findRoots is null, the tree throws back the following exception. java.lang.NullPointerExceptionFilter stack frames Stack trace - org.apache.tapestry5.corelib.components.Tree$3.render(Tree.java:150) - org.apache.tapestry5.internal.services.RenderQueueImpl.run(RenderQueueImpl.java:72) - org.apache.tapestry5.internal.services.PageRenderQueueImpl.render(PageRenderQueueImpl.java:124) - org.apache.tapestry5.internal.services.MarkupRendererTerminator.renderMarkup(MarkupRendererTerminator.java:37) - org.apache.tapestry5.services.TapestryModule$30.renderMarkup(TapestryModule.java:1979) I feel as if this may be a Tapestry tree component issue? Thanks a ton Lance! On Sat, Feb 18, 2012 at 5:08 AM, Lance Java [via Tapestry] < ml-node+s1045711n5495019...@n5.nabble.com> wrote: > Hi George, > > In you code, there should only be 2 references to HibernateCategoryDao. > 1. In AppModule > binder.bind(CategoryDao.class, HibernateCategoryDao.class); > 2. In the HibernateCategoryDao class itself > > Every other class (page, value encoder, treeModelAdapter) should reference > CategoryDao > eg @Inject CategoryDao categoryDao > > Interfaces are a contract and have no implementation details. It's much > better to code against interfaces and only be bound to the actual > implemtation at runtime for many reasons including: > 1. In your unit tests, you could inject a MockCategoryDao and not require > a > database > 2. In the future, you may need to change the implementation to a > WebServiceCategoryDao (or something else) and all you need to change is > AppModule > 3. Tapestry uses the IOC pattern (inversion of control) and actually > injects a wrapper around HibernateCategoryDao so the @Inject'ed bean is > not > actually an instance of HibernateCategoryDao (it does delegate to it > though). > 4. If you code to an interface, you can do all sorts fancy things with > proxies including the interceptor pattern > > Some further reading > http://en.wikipedia.org/wiki/Inversion_of_control > http://en.wikipedia.org/wiki/Proxy_pattern > http://en.wikipedia.org/wiki/Interceptor_pattern > > I've made a couple of mods to the code too: > > 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); > } > if (!childNodes.isEmpty()) { // if empty, the next query will fail > > Query query = session.createSQLQuery( > "select c1.id, count(c2.id) " > + "from CATEGORY c1 " > + "left join CATEGORY c2 on c2.parent_id = c1.id " > + "where c1.id in (:catIds) " > + "group by c1.id"); > > query.setParameterList("catIds", childNodes.keySet().toArray()); > List queryResult = query.list(); > > for (Iterator<Object[]> it = query.iterate(); it.hasNext(); ) { > Object[] result = it.next(); > Long childId = (Long) result[0]; > Integer grandChildCount = (Integer) result[1]; > CategoryNode childNode = childNodes.get(childId); > childNode.setHasChildren(grandChildCount != 0); > childNode.setLeaf(grandChildCount == 0); > } > } > return new ArrayList<CategoryNode>(childNodes.values()); > > Cheers, > Lance > > On 18 February 2012 02:55, George Christman <[hidden > email]<http://user/SendEmail.jtp?type=node&node=5495019&i=0>> > wrote: > > > btw, I should mention the model exception only happens while trying to > > expand > > the tree node. It produces an ajax exception. > > > > -- > > View this message in context: > > > http://tapestry.1045711.n5.nabble.com/Tapestry-TreeGrid-tp5462126p5494602.html > > > Sent from the Tapestry - User mailing list archive at Nabble.com. > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [hidden > > email]<http://user/SendEmail.jtp?type=node&node=5495019&i=1> > > For additional commands, e-mail: [hidden > > email]<http://user/SendEmail.jtp?type=node&node=5495019&i=2> > > > > > > > ------------------------------ > If you reply to this email, your message will be added to the discussion > below: > > http://tapestry.1045711.n5.nabble.com/Tapestry-TreeGrid-tp5462126p5495019.html > To unsubscribe from Tapestry TreeGrid, click > here<http://tapestry.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=5462126&code=Z2NocmlzdG1hbkBjYXJkYWRkeS5jb218NTQ2MjEyNnwxNjMyOTYxMjA3> > . > NAML<http://tapestry.1045711.n5.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml> > -- George Christman www.CarDaddy.com P.O. Box 735 Johnstown, New York -- View this message in context: http://tapestry.1045711.n5.nabble.com/Tapestry-TreeGrid-tp5462126p5495570.html Sent from the Tapestry - User mailing list archive at Nabble.com.