Rich:tree reloaded when it shouldn't be
croco Mar 13, 2014 8:39 AMI'm having troubles with rich:tree. In every page where is a tree, whenever an ajax call is executed it crashes and I get an duplicate component id error:
11:02:30,770 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-/0.0.0.0:8080-4) JSF1007: Duplicate component ID bscRpPrmF:foldersTree:j_idt278 found in view. 11:02:30,773 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-/0.0.0.0:8080-4) +id: j_id1 type: javax.faces.component.UIViewRoot@41d6afee
I think there is a problem with rich:tree because is reloaded even when it shouldn't be. I've created a very simple example:
Tree backing bean:
@ManagedBean @SessionScoped public class TreeBackingBean implements Serializable { private SimpleTreeNode<TreeObject> tree; @PostConstruct private void initBean() { tree = new TreeDataProvider().getTree(); } // tree getter/setter public SimpleTreeNode<TreeObject> getTree() { return tree; } public void setTree(SimpleTreeNode<TreeObject> tree) { this.tree = tree; } }
Tree data provider:
public class TreeDataProvider { private SimpleTreeNode<TreeObject> root; public SimpleTreeNode<TreeObject> getTree() { if (root == null) { root = new SimpleTreeNode<TreeObject>(false, null, null); // node 1.1 SimpleTreeNode<TreeObject> child = new SimpleTreeNode<TreeObject>(false, "Node 1.1", new TreeObject("Node", "1.1")); root.addChild(child.hashCode(), child); // node 1.1.1 SimpleTreeNode<TreeObject> subChild = new SimpleTreeNode<TreeObject>(true, "Leaf 1.1.1", new TreeObject("Leaf", "1.1.1")); child.addChild(subChild.hashCode(), subChild); // node 1.1.2 subChild = new SimpleTreeNode<TreeObject>(true, "Leaf 1.1.2", new TreeObject("Leaf", "1.1.2")); child.addChild(subChild.hashCode(), subChild); // node 1.2 child = new SimpleTreeNode<TreeObject>(true, "Leaf 1.2", new TreeObject("Leaf", "1.2")); root.addChild(child.hashCode(), child); // node 1.3 child = new SimpleTreeNode<TreeObject>(false, "Node 1.3", new TreeObject("Node", "1.3")); root.addChild(child.hashCode(), child); // node 1.3.1 subChild = new SimpleTreeNode<TreeObject>(true, "Leaf 1.3.1", new TreeObject("Leaf", "1.3.1")); child.addChild(subChild.hashCode(), subChild); } return root; } }
xhtml:
<h:body> <h3>Rich Tree example</h3> <h:form> <rich:tree value="#{treeBackingBean.tree}" var="node" selectionType="client" toggleType="client" styleClass="tree"> <rich:treeNode expanded="#{node.selected}"> <h:outputText value="#{node.name}" /> </rich:treeNode> </rich:tree> <br/> <h:outputText id="randomNumber" value="Random number: #{helloBean.randomNumber()}" /> <br/> <a4j:commandLink value="Ajax" render="@this" execute="@this" limitRender="true" /> </h:form> <br/> <a4j:log level="debug" /> </h:body>
So the problem is that every time commandLink is clicked, treeBackingBean.getTree() is executed. As far as I understand this is wrong. I put also an random number output just to double check if anything else is executed.
CommandLink's execute @this should define that only the command link itself should be processed and render @this defines that only command link is re rendered. So why getTree is executed? I think this is somehow connected with my duplicate id problem.