3 Replies Latest reply on Apr 11, 2009 7:26 AM by nbelaevski

    rich:tree avoind loading children nodes if not displayed

    rmemoria

      Hi,

      I have a rich tree nodes comimng from the database (using POJO with hibernate).

      The problem: At the first time the tree is displayed, it generates a query in the database for every node.

      This is the code:

      <rich:tree style="width:400px">
       <rich:recursiveTreeNodesAdaptor roots="#{adminUnits.resultList}" var="item" nodes="#{item.units}" >
       <rich:treeNode >
       #{item.name}
       </rich:treeNode>
       </rich:recursiveTreeNodesAdaptor>
      </rich:tree>
      


      Since it's a long list of root items, it takes a time to be displayed (and also on every iteration).

      Is there a way to avoid it?

      best,
      Ricardo


        • 1. Re: rich:tree avoind loading children nodes if not displayed
          nbelaevski

          Hello,

          This should not happen. Can you please post bean code and SQL statements generated?

          • 2. Re: rich:tree avoind loading children nodes if not displayed
            rmemoria

            Hi,

            I suppose the query is made for every node because the tree checks if each node has children, so the tree can put a folder or a leaf in the node.

            this is the bean that generates the root list:

            @Name("adminUnits")
            public class AdminUnitsQuery extends EntityQuery<AdministrativeUnit> {
             private static final long serialVersionUID = 6428637361635215953L;
            
             private static final String[] restrictions = {"a.workspace.id = #{defaultWorkspace.id}"};
            
             /* (non-Javadoc)
             * @see org.jboss.seam.framework.Query#getEjbql()
             */
             @Override
             public String getEjbql() {
             return "from AdministrativeUnit a where a.parent is null";
             }
            
             /* (non-Javadoc)
             * @see com.rmemoria.utils.EntityQuery#getStringRestrictions()
             */
             @Override
             protected List<String> getStringRestrictions() {
             return Arrays.asList(restrictions);
             }
            
             /* (non-Javadoc)
             * @see org.jboss.seam.framework.Query#getOrder()
             */
             @Override
             public String getOrder() {
             return "a.name.name1";
             }
            
            
            }
            



            And this is the bean:
            @Entity
            public class AdministrativeUnit extends WSObject implements TreeNode {
             private static final long serialVersionUID = 7777075173601864769L;
            
             @Id
             @GeneratedValue(strategy=GenerationType.AUTO)
             private Integer id;
            
             private LocalizedNameComp name = new LocalizedNameComp();
            
             @ManyToOne
             @JoinColumn(name="PARENT_ID")
             private AdministrativeUnit parent;
            
             @OneToMany(mappedBy="parent",fetch=FetchType.LAZY)
             @OrderBy(clause="NAME1")
             private List<AdministrativeUnit> units = new ArrayList<AdministrativeUnit>();
            
             @Column(length=50)
             private String legacyId;
            
             /* (non-Javadoc)
             * @see java.lang.Object#toString()
             */
             @Override
             public String toString() {
             return getName().toString();
             }
            
             public Enumeration children() {
             return Collections.enumeration(getUnits());
             }
            
             public boolean getAllowsChildren() {
             return true;
             }
            
             public TreeNode getChildAt(int childIndex) {
             return getUnits().get(childIndex);
             }
            
             public int getChildCount() {
             return getUnits().size();
             }
            
             public int getIndex(TreeNode node) {
             return getUnits().indexOf(node);
             }
            
             public boolean isLeaf() {
             return true;
             }
            
            // getters and setters ommited
            }
            


            Thanks for the response,
            Ricardo

            • 3. Re: rich:tree avoind loading children nodes if not displayed
              nbelaevski

               

              "rmemoria" wrote:
              I suppose the query is made for every node because the tree checks if each node has children, so the tree can put a folder or a leaf in the node.

              Probably, that's the cause. If it's so then you can workaround the problem by distinguishing between iterator() and size() List methods called and fetch only row count if size is called, not the data itself. Unfortunately, tree has to call this method, there's no other way to determine whether node is leaf or not, because children nodes are not rendered at all when parent is collapsed and mode is not "client".