Hi George

As I said, my hibernate is a bit rusty. What I have given you there is a
JDBC query where each question mark represents a parameter which is later
set by Query.setLong(int paramIndex, Long value). You might need to
research or chat on hibernate forums to turn it into a hibernate friendly
query. Actually, I just looked at the hibernate javadoc and it says that it
supports JDBC style '?' parameters so it might just work but I'm not 100%.
You could always look at using a hibernate criteria query and using a
projection to get the count() of children. Again, ask on the hibernate
forums for this.

<rant>
I actually really dislike hibernate because I think it makes smart people
write stupid code. I have turned on SQL logging on hibernate applications
only to be disgusted by seeing many unnecessary extra queries, joins and
n+1 selects issues. If the developers were coding their queries by hand,
this would have never happened. I happen to prefer iBatis / myBatis for
it's hands on approach. Since the db is often the slowest component in your
system, I hate to be so far abstracted from it.
</rant>

Apart from that your code looks ok although I would probably make the DAO a
service and add it to Tapestry's IOC registry and then @Inject the DAO.
What you have at the moment should work though so it's probably best to get
the query working first.

Good luck,
Lance.

On Thursday, 16 February 2012, George Christman <gchrist...@cardaddy.com>
wrote:
> 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.

Reply via email to